Changeset 745 for trunk/server/source3/libsmb/clispnego.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
source3/libsmb/clispnego.c (modified) (28 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/libsmb/clispnego.c
r590 r745 5 5 Copyright (C) Jim McDonough <[email protected]> 2002 6 6 Copyright (C) Luke Howard 2003 7 7 8 8 9 This program is free software; you can redistribute it and/or modify … … 23 24 #include "../libcli/auth/spnego.h" 24 25 #include "smb_krb5.h" 25 26 /* 27 generate a negTokenInit packet given a GUID, a list of supported 28 OIDs (the mechanisms) and a principal name string 29 */ 30 DATA_BLOB spnego_gen_negTokenInit(char guid[16], 31 const char *OIDs[], 26 #include "../lib/util/asn1.h" 27 28 /* 29 generate a negTokenInit packet given a list of supported 30 OIDs (the mechanisms) a blob, and a principal name string 31 */ 32 33 DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx, 34 const char *OIDs[], 35 DATA_BLOB *psecblob, 32 36 const char *principal) 33 37 { … … 41 45 } 42 46 43 asn1_write(data, guid, 16);44 47 asn1_push_tag(data,ASN1_APPLICATION(0)); 45 48 asn1_write_OID(data,OID_SPNEGO); … … 55 58 asn1_pop_tag(data); 56 59 57 asn1_push_tag(data, ASN1_CONTEXT(3)); 58 asn1_push_tag(data, ASN1_SEQUENCE(0)); 59 asn1_push_tag(data, ASN1_CONTEXT(0)); 60 asn1_write_GeneralString(data,principal); 61 asn1_pop_tag(data); 62 asn1_pop_tag(data); 63 asn1_pop_tag(data); 60 if (psecblob && psecblob->length && psecblob->data) { 61 asn1_push_tag(data, ASN1_CONTEXT(2)); 62 asn1_write_OctetString(data,psecblob->data, 63 psecblob->length); 64 asn1_pop_tag(data); 65 } 66 67 if (principal) { 68 asn1_push_tag(data, ASN1_CONTEXT(3)); 69 asn1_push_tag(data, ASN1_SEQUENCE(0)); 70 asn1_push_tag(data, ASN1_CONTEXT(0)); 71 asn1_write_GeneralString(data,principal); 72 asn1_pop_tag(data); 73 asn1_pop_tag(data); 74 asn1_pop_tag(data); 75 } 64 76 65 77 asn1_pop_tag(data); … … 72 84 } 73 85 74 ret = data_blob(data->data, data->length); 75 asn1_free(data); 76 77 return ret; 78 } 79 80 /* 81 Generate a negTokenInit as used by the client side ... It has a mechType 82 (OID), and a mechToken (a security blob) ... 83 84 Really, we need to break out the NTLMSSP stuff as well, because it could be 85 raw in the packets! 86 */ 87 DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) 88 { 89 ASN1_DATA *data; 90 DATA_BLOB ret; 91 92 data = asn1_init(talloc_tos()); 93 if (data == NULL) { 94 return data_blob_null; 95 } 96 97 asn1_push_tag(data, ASN1_APPLICATION(0)); 98 asn1_write_OID(data,OID_SPNEGO); 99 asn1_push_tag(data, ASN1_CONTEXT(0)); 100 asn1_push_tag(data, ASN1_SEQUENCE(0)); 101 102 asn1_push_tag(data, ASN1_CONTEXT(0)); 103 asn1_push_tag(data, ASN1_SEQUENCE(0)); 104 asn1_write_OID(data, OID); 105 asn1_pop_tag(data); 106 asn1_pop_tag(data); 107 108 asn1_push_tag(data, ASN1_CONTEXT(2)); 109 asn1_write_OctetString(data,blob.data,blob.length); 110 asn1_pop_tag(data); 111 112 asn1_pop_tag(data); 113 asn1_pop_tag(data); 114 115 asn1_pop_tag(data); 116 117 if (data->has_error) { 118 DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data->ofs)); 119 } 120 121 ret = data_blob(data->data, data->length); 86 ret = data_blob_talloc(ctx, data->data, data->length); 122 87 asn1_free(data); 123 88 … … 129 94 OIDs (the mechanisms) and a principal name string 130 95 */ 131 bool spnego_parse_negTokenInit(DATA_BLOB blob, 96 bool spnego_parse_negTokenInit(TALLOC_CTX *ctx, 97 DATA_BLOB blob, 132 98 char *OIDs[ASN1_MAX_OIDS], 133 char **principal) 99 char **principal, 100 DATA_BLOB *secblob) 134 101 { 135 102 int i; … … 160 127 asn1_start_tag(data,ASN1_SEQUENCE(0)); 161 128 for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) { 162 const char *oid_str = NULL; 163 asn1_read_OID(data,talloc_autofree_context(),&oid_str); 164 OIDs[i] = CONST_DISCARD(char *, oid_str); 129 asn1_read_OID(data,ctx, &OIDs[i]); 165 130 } 166 131 OIDs[i] = NULL; … … 168 133 asn1_end_tag(data); 169 134 170 *principal = NULL; 135 if (principal) { 136 *principal = NULL; 137 } 138 if (secblob) { 139 *secblob = data_blob_null; 140 } 171 141 172 142 /* … … 191 161 192 162 if (asn1_peek_tag(data, ASN1_CONTEXT(2))) { 163 193 164 /* mechToken [2] OCTET STRING OPTIONAL */ 194 DATA_BLOB token;195 165 asn1_start_tag(data, ASN1_CONTEXT(2)); 196 asn1_read_OctetString(data, talloc_autofree_context(), 197 &token); 198 asn1_end_tag(data); 199 /* Throw away the token - not used. */ 200 data_blob_free(&token); 166 asn1_read_OctetString(data, ctx, &sblob); 167 asn1_end_tag(data); 168 if (secblob) { 169 *secblob = sblob; 170 } else { 171 data_blob_free(&sblob); 172 } 201 173 } 202 174 203 175 if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { 176 204 177 /* mechListMIC [3] OCTET STRING OPTIONAL */ 205 178 asn1_start_tag(data, ASN1_CONTEXT(3)); 206 179 asn1_start_tag(data, ASN1_SEQUENCE(0)); 207 180 asn1_start_tag(data, ASN1_CONTEXT(0)); 208 asn1_read_GeneralString(data,talloc_autofree_context(), 209 principal); 210 asn1_end_tag(data); 211 asn1_end_tag(data); 212 asn1_end_tag(data); 181 asn1_read_GeneralString(data, ctx, &princ); 182 asn1_end_tag(data); 183 asn1_end_tag(data); 184 asn1_end_tag(data); 185 if (principal) { 186 *principal = princ; 187 } else { 188 TALLOC_FREE(princ); 189 } 213 190 } 214 191 … … 221 198 if (data->has_error) { 222 199 int j; 223 TALLOC_FREE(*principal); 200 if (principal) { 201 TALLOC_FREE(*principal); 202 } 203 if (secblob) { 204 data_blob_free(secblob); 205 } 224 206 for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { 225 207 TALLOC_FREE(OIDs[j]); … … 232 214 233 215 /* 234 generate a negTokenTarg packet given a list of OIDs and a security blob235 */236 DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob)237 {238 int i;239 ASN1_DATA *data;240 DATA_BLOB ret;241 242 data = asn1_init(talloc_tos());243 if (data == NULL) {244 return data_blob_null;245 }246 247 asn1_push_tag(data, ASN1_APPLICATION(0));248 asn1_write_OID(data,OID_SPNEGO);249 asn1_push_tag(data, ASN1_CONTEXT(0));250 asn1_push_tag(data, ASN1_SEQUENCE(0));251 252 asn1_push_tag(data, ASN1_CONTEXT(0));253 asn1_push_tag(data, ASN1_SEQUENCE(0));254 for (i=0; OIDs[i]; i++) {255 asn1_write_OID(data,OIDs[i]);256 }257 asn1_pop_tag(data);258 asn1_pop_tag(data);259 260 asn1_push_tag(data, ASN1_CONTEXT(2));261 asn1_write_OctetString(data,blob.data,blob.length);262 asn1_pop_tag(data);263 264 asn1_pop_tag(data);265 asn1_pop_tag(data);266 267 asn1_pop_tag(data);268 269 if (data->has_error) {270 DEBUG(1,("Failed to build negTokenTarg at offset %d\n", (int)data->ofs));271 }272 273 ret = data_blob(data->data, data->length);274 asn1_free(data);275 276 return ret;277 }278 279 /*280 parse a negTokenTarg packet giving a list of OIDs and a security blob281 */282 bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob)283 {284 int i;285 ASN1_DATA *data;286 287 data = asn1_init(talloc_tos());288 if (data == NULL) {289 return false;290 }291 292 asn1_load(data, blob);293 asn1_start_tag(data, ASN1_APPLICATION(0));294 asn1_check_OID(data,OID_SPNEGO);295 asn1_start_tag(data, ASN1_CONTEXT(0));296 asn1_start_tag(data, ASN1_SEQUENCE(0));297 298 asn1_start_tag(data, ASN1_CONTEXT(0));299 asn1_start_tag(data, ASN1_SEQUENCE(0));300 for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {301 const char *oid_str = NULL;302 asn1_read_OID(data,talloc_autofree_context(),&oid_str);303 OIDs[i] = CONST_DISCARD(char *, oid_str);304 }305 OIDs[i] = NULL;306 asn1_end_tag(data);307 asn1_end_tag(data);308 309 /* Skip any optional req_flags that are sent per RFC 4178 */310 if (asn1_peek_tag(data, ASN1_CONTEXT(1))) {311 uint8 flags;312 313 asn1_start_tag(data, ASN1_CONTEXT(1));314 asn1_start_tag(data, ASN1_BIT_STRING);315 while (asn1_tag_remaining(data) > 0)316 asn1_read_uint8(data, &flags);317 asn1_end_tag(data);318 asn1_end_tag(data);319 }320 321 asn1_start_tag(data, ASN1_CONTEXT(2));322 asn1_read_OctetString(data,talloc_autofree_context(),secblob);323 asn1_end_tag(data);324 325 asn1_end_tag(data);326 asn1_end_tag(data);327 328 asn1_end_tag(data);329 330 if (data->has_error) {331 int j;332 data_blob_free(secblob);333 for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) {334 TALLOC_FREE(OIDs[j]);335 }336 DEBUG(1,("Failed to parse negTokenTarg at offset %d\n", (int)data->ofs));337 asn1_free(data);338 return False;339 }340 341 asn1_free(data);342 return True;343 }344 345 /*346 216 generate a krb5 GSS-API wrapper packet given a ticket 347 217 */ 348 DATA_BLOB spnego_gen_krb5_wrap( const DATA_BLOB ticket, const uint8 tok_id[2])218 DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8 tok_id[2]) 349 219 { 350 220 ASN1_DATA *data; … … 367 237 } 368 238 369 ret = data_blob (data->data, data->length);239 ret = data_blobdata->data, data->length); 370 240 asn1_free(data); 371 241 … … 376 246 parse a krb5 GSS-API wrapper packet giving a ticket 377 247 */ 378 bool spnego_parse_krb5_wrap( DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])248 bool spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) 379 249 { 380 250 bool ret; … … 398 268 asn1_read(data, tok_id, 2); 399 269 data_remaining -= 2; 400 *ticket = data_blob (NULL, data_remaining);270 *ticket = data_blobNULL, data_remaining); 401 271 asn1_read(data, ticket->data, ticket->length); 402 272 } … … 417 287 418 288 /* 419 generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY 420 kerberos session setup 421 */ 422 int spnego_gen_negTokenTarg(const char *principal, int time_offset, 423 DATA_BLOB *targ, 289 generate a SPNEGO krb5 negTokenInit packet, ready for a EXTENDED_SECURITY 290 kerberos session setup 291 */ 292 int spnego_gen_krb5_negTokenInit(TALLOC_CTX *ctx, 293 const char *principal, int time_offset, 294 DATA_BLOB *targ, 424 295 DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, 425 296 time_t *expire_time) … … 430 301 431 302 /* get a kerberos ticket for the service and extract the session key */ 432 retval = cli_krb5_get_ticket( principal, time_offset,433 &tkt, session_key_krb5, extra_ap_opts, NULL,434 expire_time, NULL);435 436 if (retval) 303 retval = cli_krb5_get_ticket(principal, time_offset, 304 305 306 expire_time, NULL); 307 if (retval) 437 308 return retval; 309 438 310 439 311 /* wrap that up in a nice GSS-API wrapping */ 440 tkt_wrapped = spnego_gen_krb5_wrap( tkt, TOK_ID_KRB_AP_REQ);312 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); 441 313 442 314 /* and wrap that in a shiny SPNEGO wrapper */ 443 *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped);315 *targ = ); 444 316 445 317 data_blob_free(&tkt_wrapped); … … 453 325 parse a spnego NTLMSSP challenge packet giving two security blobs 454 326 */ 455 bool spnego_parse_challenge( const DATA_BLOB blob,327 bool spnego_parse_challenge(const DATA_BLOB blob, 456 328 DATA_BLOB *chal1, DATA_BLOB *chal2) 457 329 { … … 480 352 481 353 asn1_start_tag(data,ASN1_CONTEXT(2)); 482 asn1_read_OctetString(data, talloc_autofree_context(), chal1);354 asn1_read_OctetString(data, , chal1); 483 355 asn1_end_tag(data); 484 356 … … 486 358 if (asn1_tag_remaining(data)) { 487 359 asn1_start_tag(data,ASN1_CONTEXT(3)); 488 asn1_read_OctetString(data, talloc_autofree_context(), chal2);360 asn1_read_OctetString(data, , chal2); 489 361 asn1_end_tag(data); 490 362 } … … 508 380 generate a SPNEGO auth packet. This will contain the encrypted passwords 509 381 */ 510 DATA_BLOB spnego_gen_auth( DATA_BLOB blob)382 DATA_BLOB spnego_gen_auth(DATA_BLOB blob) 511 383 { 512 384 ASN1_DATA *data; … … 526 398 asn1_pop_tag(data); 527 399 528 ret = data_blob (data->data, data->length);400 ret = data_blobdata->data, data->length); 529 401 530 402 asn1_free(data); … … 536 408 parse a SPNEGO auth packet. This contains the encrypted passwords 537 409 */ 538 bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) 410 bool spnego_parse_auth_and_mic(TALLOC_CTX *ctx, DATA_BLOB blob, 411 DATA_BLOB *auth, DATA_BLOB *signature) 539 412 { 540 413 ssize_t len; … … 554 427 } 555 428 556 *auth = data_blob_talloc( talloc_tos(),429 *auth = data_blob_talloc(, 557 430 token.negTokenTarg.responseToken.data, 558 431 token.negTokenTarg.responseToken.length); 432 433 434 435 436 437 438 439 440 441 559 442 spnego_free_data(&token); 560 443 … … 562 445 } 563 446 447 448 449 450 451 564 452 /* 565 453 generate a minimal SPNEGO response packet. Doesn't contain much. 566 454 */ 567 DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, 568 const char *mechOID) 455 DATA_BLOB spnego_gen_auth_response_and_mic(TALLOC_CTX *ctx, 456 NTSTATUS nt_status, 457 const char *mechOID, 458 DATA_BLOB *reply, 459 DATA_BLOB *mechlistMIC) 569 460 { 570 461 ASN1_DATA *data; … … 603 494 } 604 495 605 asn1_pop_tag(data); 606 asn1_pop_tag(data); 607 608 ret = data_blob(data->data, data->length); 496 if (mechlistMIC && mechlistMIC->data != NULL) { 497 asn1_push_tag(data, ASN1_CONTEXT(3)); 498 asn1_write_OctetString(data, 499 mechlistMIC->data, 500 mechlistMIC->length); 501 asn1_pop_tag(data); 502 } 503 504 asn1_pop_tag(data); 505 asn1_pop_tag(data); 506 507 ret = data_blob_talloc(ctx, data->data, data->length); 609 508 asn1_free(data); 610 509 return ret; 611 510 } 612 511 512 513 514 515 516 517 518 613 519 /* 614 520 parse a SPNEGO auth packet. This contains the encrypted passwords 615 521 */ 616 bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, 522 bool spnego_parse_auth_response(TALLOC_CTX *ctx, 523 DATA_BLOB blob, NTSTATUS nt_status, 617 524 const char *mechOID, 618 525 DATA_BLOB *auth) … … 650 557 if (asn1_tag_remaining(data)) { 651 558 asn1_start_tag(data,ASN1_CONTEXT(2)); 652 asn1_read_OctetString(data, talloc_autofree_context(), auth);559 asn1_read_OctetString(data, , auth); 653 560 asn1_end_tag(data); 654 561 } … … 664 571 DATA_BLOB mechList = data_blob_null; 665 572 asn1_start_tag(data, ASN1_CONTEXT(3)); 666 asn1_read_OctetString(data, talloc_autofree_context(), &mechList);573 asn1_read_OctetString(data, , &mechList); 667 574 asn1_end_tag(data); 668 575 data_blob_free(&mechList); … … 684 591 return True; 685 592 } 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630
Note:
See TracChangeset
for help on using the changeset viewer.
