diff options
Diffstat (limited to 'fs/cifs/asn1.c')
-rw-r--r-- | fs/cifs/asn1.c | 103 |
1 files changed, 42 insertions, 61 deletions
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index a20bea59893..cfd1ce34e0b 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c | |||
@@ -492,17 +492,13 @@ compare_oid(unsigned long *oid1, unsigned int oid1len, | |||
492 | 492 | ||
493 | int | 493 | int |
494 | decode_negTokenInit(unsigned char *security_blob, int length, | 494 | decode_negTokenInit(unsigned char *security_blob, int length, |
495 | enum securityEnum *secType) | 495 | struct TCP_Server_Info *server) |
496 | { | 496 | { |
497 | struct asn1_ctx ctx; | 497 | struct asn1_ctx ctx; |
498 | unsigned char *end; | 498 | unsigned char *end; |
499 | unsigned char *sequence_end; | 499 | unsigned char *sequence_end; |
500 | unsigned long *oid = NULL; | 500 | unsigned long *oid = NULL; |
501 | unsigned int cls, con, tag, oidlen, rc; | 501 | unsigned int cls, con, tag, oidlen, rc; |
502 | bool use_ntlmssp = false; | ||
503 | bool use_kerberos = false; | ||
504 | bool use_kerberosu2u = false; | ||
505 | bool use_mskerberos = false; | ||
506 | 502 | ||
507 | /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ | 503 | /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ |
508 | 504 | ||
@@ -510,11 +506,11 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
510 | 506 | ||
511 | /* GSSAPI header */ | 507 | /* GSSAPI header */ |
512 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 508 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
513 | cFYI(1, ("Error decoding negTokenInit header")); | 509 | cFYI(1, "Error decoding negTokenInit header"); |
514 | return 0; | 510 | return 0; |
515 | } else if ((cls != ASN1_APL) || (con != ASN1_CON) | 511 | } else if ((cls != ASN1_APL) || (con != ASN1_CON) |
516 | || (tag != ASN1_EOC)) { | 512 | || (tag != ASN1_EOC)) { |
517 | cFYI(1, ("cls = %d con = %d tag = %d", cls, con, tag)); | 513 | cFYI(1, "cls = %d con = %d tag = %d", cls, con, tag); |
518 | return 0; | 514 | return 0; |
519 | } | 515 | } |
520 | 516 | ||
@@ -535,56 +531,52 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
535 | 531 | ||
536 | /* SPNEGO OID not present or garbled -- bail out */ | 532 | /* SPNEGO OID not present or garbled -- bail out */ |
537 | if (!rc) { | 533 | if (!rc) { |
538 | cFYI(1, ("Error decoding negTokenInit header")); | 534 | cFYI(1, "Error decoding negTokenInit header"); |
539 | return 0; | 535 | return 0; |
540 | } | 536 | } |
541 | 537 | ||
542 | /* SPNEGO */ | 538 | /* SPNEGO */ |
543 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 539 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
544 | cFYI(1, ("Error decoding negTokenInit")); | 540 | cFYI(1, "Error decoding negTokenInit"); |
545 | return 0; | 541 | return 0; |
546 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON) | 542 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON) |
547 | || (tag != ASN1_EOC)) { | 543 | || (tag != ASN1_EOC)) { |
548 | cFYI(1, | 544 | cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0", |
549 | ("cls = %d con = %d tag = %d end = %p (%d) exit 0", | 545 | cls, con, tag, end, *end); |
550 | cls, con, tag, end, *end)); | ||
551 | return 0; | 546 | return 0; |
552 | } | 547 | } |
553 | 548 | ||
554 | /* negTokenInit */ | 549 | /* negTokenInit */ |
555 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 550 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
556 | cFYI(1, ("Error decoding negTokenInit")); | 551 | cFYI(1, "Error decoding negTokenInit"); |
557 | return 0; | 552 | return 0; |
558 | } else if ((cls != ASN1_UNI) || (con != ASN1_CON) | 553 | } else if ((cls != ASN1_UNI) || (con != ASN1_CON) |
559 | || (tag != ASN1_SEQ)) { | 554 | || (tag != ASN1_SEQ)) { |
560 | cFYI(1, | 555 | cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1", |
561 | ("cls = %d con = %d tag = %d end = %p (%d) exit 1", | 556 | cls, con, tag, end, *end); |
562 | cls, con, tag, end, *end)); | ||
563 | return 0; | 557 | return 0; |
564 | } | 558 | } |
565 | 559 | ||
566 | /* sequence */ | 560 | /* sequence */ |
567 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 561 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
568 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); | 562 | cFYI(1, "Error decoding 2nd part of negTokenInit"); |
569 | return 0; | 563 | return 0; |
570 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON) | 564 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON) |
571 | || (tag != ASN1_EOC)) { | 565 | || (tag != ASN1_EOC)) { |
572 | cFYI(1, | 566 | cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0", |
573 | ("cls = %d con = %d tag = %d end = %p (%d) exit 0", | 567 | cls, con, tag, end, *end); |
574 | cls, con, tag, end, *end)); | ||
575 | return 0; | 568 | return 0; |
576 | } | 569 | } |
577 | 570 | ||
578 | /* sequence of */ | 571 | /* sequence of */ |
579 | if (asn1_header_decode | 572 | if (asn1_header_decode |
580 | (&ctx, &sequence_end, &cls, &con, &tag) == 0) { | 573 | (&ctx, &sequence_end, &cls, &con, &tag) == 0) { |
581 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); | 574 | cFYI(1, "Error decoding 2nd part of negTokenInit"); |
582 | return 0; | 575 | return 0; |
583 | } else if ((cls != ASN1_UNI) || (con != ASN1_CON) | 576 | } else if ((cls != ASN1_UNI) || (con != ASN1_CON) |
584 | || (tag != ASN1_SEQ)) { | 577 | || (tag != ASN1_SEQ)) { |
585 | cFYI(1, | 578 | cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1", |
586 | ("cls = %d con = %d tag = %d end = %p (%d) exit 1", | 579 | cls, con, tag, end, *end); |
587 | cls, con, tag, end, *end)); | ||
588 | return 0; | 580 | return 0; |
589 | } | 581 | } |
590 | 582 | ||
@@ -592,37 +584,33 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
592 | while (!asn1_eoc_decode(&ctx, sequence_end)) { | 584 | while (!asn1_eoc_decode(&ctx, sequence_end)) { |
593 | rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); | 585 | rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); |
594 | if (!rc) { | 586 | if (!rc) { |
595 | cFYI(1, | 587 | cFYI(1, "Error decoding negTokenInit hdr exit2"); |
596 | ("Error decoding negTokenInit hdr exit2")); | ||
597 | return 0; | 588 | return 0; |
598 | } | 589 | } |
599 | if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { | 590 | if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { |
600 | if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) { | 591 | if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) { |
601 | 592 | ||
602 | cFYI(1, ("OID len = %d oid = 0x%lx 0x%lx " | 593 | cFYI(1, "OID len = %d oid = 0x%lx 0x%lx " |
603 | "0x%lx 0x%lx", oidlen, *oid, | 594 | "0x%lx 0x%lx", oidlen, *oid, |
604 | *(oid + 1), *(oid + 2), *(oid + 3))); | 595 | *(oid + 1), *(oid + 2), *(oid + 3)); |
605 | 596 | ||
606 | if (compare_oid(oid, oidlen, MSKRB5_OID, | 597 | if (compare_oid(oid, oidlen, MSKRB5_OID, |
607 | MSKRB5_OID_LEN) && | 598 | MSKRB5_OID_LEN)) |
608 | !use_mskerberos) | 599 | server->sec_mskerberos = true; |
609 | use_mskerberos = true; | ||
610 | else if (compare_oid(oid, oidlen, KRB5U2U_OID, | 600 | else if (compare_oid(oid, oidlen, KRB5U2U_OID, |
611 | KRB5U2U_OID_LEN) && | 601 | KRB5U2U_OID_LEN)) |
612 | !use_kerberosu2u) | 602 | server->sec_kerberosu2u = true; |
613 | use_kerberosu2u = true; | ||
614 | else if (compare_oid(oid, oidlen, KRB5_OID, | 603 | else if (compare_oid(oid, oidlen, KRB5_OID, |
615 | KRB5_OID_LEN) && | 604 | KRB5_OID_LEN)) |
616 | !use_kerberos) | 605 | server->sec_kerberos = true; |
617 | use_kerberos = true; | ||
618 | else if (compare_oid(oid, oidlen, NTLMSSP_OID, | 606 | else if (compare_oid(oid, oidlen, NTLMSSP_OID, |
619 | NTLMSSP_OID_LEN)) | 607 | NTLMSSP_OID_LEN)) |
620 | use_ntlmssp = true; | 608 | server->sec_ntlmssp = true; |
621 | 609 | ||
622 | kfree(oid); | 610 | kfree(oid); |
623 | } | 611 | } |
624 | } else { | 612 | } else { |
625 | cFYI(1, ("Should be an oid what is going on?")); | 613 | cFYI(1, "Should be an oid what is going on?"); |
626 | } | 614 | } |
627 | } | 615 | } |
628 | 616 | ||
@@ -632,54 +620,47 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
632 | no mechListMic (e.g. NTLMSSP instead of KRB5) */ | 620 | no mechListMic (e.g. NTLMSSP instead of KRB5) */ |
633 | if (ctx.error == ASN1_ERR_DEC_EMPTY) | 621 | if (ctx.error == ASN1_ERR_DEC_EMPTY) |
634 | goto decode_negtoken_exit; | 622 | goto decode_negtoken_exit; |
635 | cFYI(1, ("Error decoding last part negTokenInit exit3")); | 623 | cFYI(1, "Error decoding last part negTokenInit exit3"); |
636 | return 0; | 624 | return 0; |
637 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { | 625 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { |
638 | /* tag = 3 indicating mechListMIC */ | 626 | /* tag = 3 indicating mechListMIC */ |
639 | cFYI(1, ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)", | 627 | cFYI(1, "Exit 4 cls = %d con = %d tag = %d end = %p (%d)", |
640 | cls, con, tag, end, *end)); | 628 | cls, con, tag, end, *end); |
641 | return 0; | 629 | return 0; |
642 | } | 630 | } |
643 | 631 | ||
644 | /* sequence */ | 632 | /* sequence */ |
645 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 633 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
646 | cFYI(1, ("Error decoding last part negTokenInit exit5")); | 634 | cFYI(1, "Error decoding last part negTokenInit exit5"); |
647 | return 0; | 635 | return 0; |
648 | } else if ((cls != ASN1_UNI) || (con != ASN1_CON) | 636 | } else if ((cls != ASN1_UNI) || (con != ASN1_CON) |
649 | || (tag != ASN1_SEQ)) { | 637 | || (tag != ASN1_SEQ)) { |
650 | cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d)", | 638 | cFYI(1, "cls = %d con = %d tag = %d end = %p (%d)", |
651 | cls, con, tag, end, *end)); | 639 | cls, con, tag, end, *end); |
652 | } | 640 | } |
653 | 641 | ||
654 | /* sequence of */ | 642 | /* sequence of */ |
655 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 643 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
656 | cFYI(1, ("Error decoding last part negTokenInit exit 7")); | 644 | cFYI(1, "Error decoding last part negTokenInit exit 7"); |
657 | return 0; | 645 | return 0; |
658 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { | 646 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { |
659 | cFYI(1, ("Exit 8 cls = %d con = %d tag = %d end = %p (%d)", | 647 | cFYI(1, "Exit 8 cls = %d con = %d tag = %d end = %p (%d)", |
660 | cls, con, tag, end, *end)); | 648 | cls, con, tag, end, *end); |
661 | return 0; | 649 | return 0; |
662 | } | 650 | } |
663 | 651 | ||
664 | /* general string */ | 652 | /* general string */ |
665 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 653 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
666 | cFYI(1, ("Error decoding last part negTokenInit exit9")); | 654 | cFYI(1, "Error decoding last part negTokenInit exit9"); |
667 | return 0; | 655 | return 0; |
668 | } else if ((cls != ASN1_UNI) || (con != ASN1_PRI) | 656 | } else if ((cls != ASN1_UNI) || (con != ASN1_PRI) |
669 | || (tag != ASN1_GENSTR)) { | 657 | || (tag != ASN1_GENSTR)) { |
670 | cFYI(1, ("Exit10 cls = %d con = %d tag = %d end = %p (%d)", | 658 | cFYI(1, "Exit10 cls = %d con = %d tag = %d end = %p (%d)", |
671 | cls, con, tag, end, *end)); | 659 | cls, con, tag, end, *end); |
672 | return 0; | 660 | return 0; |
673 | } | 661 | } |
674 | cFYI(1, ("Need to call asn1_octets_decode() function for %s", | 662 | cFYI(1, "Need to call asn1_octets_decode() function for %s", |
675 | ctx.pointer)); /* is this UTF-8 or ASCII? */ | 663 | ctx.pointer); /* is this UTF-8 or ASCII? */ |
676 | decode_negtoken_exit: | 664 | decode_negtoken_exit: |
677 | if (use_kerberos) | ||
678 | *secType = Kerberos; | ||
679 | else if (use_mskerberos) | ||
680 | *secType = MSKerberos; | ||
681 | else if (use_ntlmssp) | ||
682 | *secType = RawNTLMSSP; | ||
683 | |||
684 | return 1; | 665 | return 1; |
685 | } | 666 | } |