~ubuntu-branches/ubuntu/maverick/openldap/maverick-proposed

« back to all changes in this revision

Viewing changes to libraries/libldap/tls_o.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug
  • Date: 2009-09-07 13:41:10 UTC
  • mto: This revision was merged to the branch mainline in revision 19.
  • Revision ID: james.westby@ubuntu.com-20090907134110-jsdrvn0atu1fex4m
Tags: upstream-2.4.18
ImportĀ upstreamĀ versionĀ 2.4.18

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* tls_o.c - Handle tls/ssl using SSLeay or OpenSSL */
2
 
/* $OpenLDAP: pkg/ldap/libraries/libldap/tls_o.c,v 1.5.2.4 2009/07/01 23:04:49 quanah Exp $ */
 
1
/* tls_o.c - Handle tls/ssl using OpenSSL */
 
2
/* $OpenLDAP: pkg/ldap/libraries/libldap/tls_o.c,v 1.5.2.7 2009/08/25 22:58:08 quanah Exp $ */
3
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
4
 *
5
5
 * Copyright 2008-2009 The OpenLDAP Foundation.
466
466
        X509 *x;
467
467
        const char *name;
468
468
        char *ptr;
469
 
        int ntype = IS_DNS;
 
469
        int ntype = IS_DNS, nlen;
470
470
#ifdef LDAP_PF_INET6
471
471
        struct in6_addr addr;
472
472
#else
480
480
        } else {
481
481
                name = name_in;
482
482
        }
 
483
        nlen = strlen(name);
483
484
 
484
485
        x = tlso_get_cert(s);
485
486
        if (!x) {
513
514
                ex = X509_get_ext(x, i);
514
515
                alt = X509V3_EXT_d2i(ex);
515
516
                if (alt) {
516
 
                        int n, len1 = 0, len2 = 0;
 
517
                        int n, len2 = 0;
517
518
                        char *domain = NULL;
518
519
                        GENERAL_NAME *gn;
519
520
 
520
521
                        if (ntype == IS_DNS) {
521
 
                                len1 = strlen(name);
522
522
                                domain = strchr(name, '.');
523
523
                                if (domain) {
524
 
                                        len2 = len1 - (domain-name);
 
524
                                        len2 = nlen - (domain-name);
525
525
                                }
526
526
                        }
527
527
                        n = sk_GENERAL_NAME_num(alt);
539
539
                                        if (sl == 0) continue;
540
540
 
541
541
                                        /* Is this an exact match? */
542
 
                                        if ((len1 == sl) && !strncasecmp(name, sn, len1)) {
 
542
                                        if ((nlen == sl) && !strncasecmp(name, sn, nlen)) {
543
543
                                                break;
544
544
                                        }
545
545
 
579
579
 
580
580
        if (ret != LDAP_SUCCESS) {
581
581
                X509_NAME *xn;
582
 
                char buf[2048];
583
 
                buf[0] = '\0';
 
582
                X509_NAME_ENTRY *ne;
 
583
                ASN1_OBJECT *obj;
 
584
                ASN1_STRING *cn = NULL;
 
585
                int navas;
 
586
 
 
587
                /* find the last CN */
 
588
                obj = OBJ_nid2obj( NID_commonName );
 
589
                if ( !obj ) goto no_cn; /* should never happen */
584
590
 
585
591
                xn = X509_get_subject_name(x);
586
 
                if( X509_NAME_get_text_by_NID( xn, NID_commonName,
587
 
                        buf, sizeof(buf)) == -1)
 
592
                navas = X509_NAME_entry_count( xn );
 
593
                for ( i=navas-1; i>=0; i-- ) {
 
594
                        ne = X509_NAME_get_entry( xn, i );
 
595
                        if ( !OBJ_cmp( ne->object, obj )) {
 
596
                                cn = X509_NAME_ENTRY_get_data( ne );
 
597
                                break;
 
598
                        }
 
599
                }
 
600
 
 
601
                if( !cn )
588
602
                {
 
603
no_cn:
589
604
                        Debug( LDAP_DEBUG_ANY,
590
605
                                "TLS: unable to get common name from peer certificate.\n",
591
606
                                0, 0, 0 );
596
611
                        ld->ld_error = LDAP_STRDUP(
597
612
                                _("TLS: unable to get CN from peer certificate"));
598
613
 
599
 
                } else if (strcasecmp(name, buf) == 0 ) {
 
614
                } else if ( cn->length == nlen &&
 
615
                        strncasecmp( name, (char *) cn->data, nlen ) == 0 ) {
600
616
                        ret = LDAP_SUCCESS;
601
617
 
602
 
                } else if (( buf[0] == '*' ) && ( buf[1] == '.' )) {
 
618
                } else if (( cn->data[0] == '*' ) && ( cn->data[1] == '.' )) {
603
619
                        char *domain = strchr(name, '.');
604
620
                        if( domain ) {
605
 
                                size_t dlen = 0;
606
 
                                size_t sl;
 
621
                                int dlen;
607
622
 
608
 
                                sl = strlen(name);
609
 
                                dlen = sl - (domain-name);
610
 
                                sl = strlen(buf);
 
623
                                dlen = nlen - (domain-name);
611
624
 
612
625
                                /* Is this a wildcard match? */
613
 
                                if ((dlen == sl-1) && !strncasecmp(domain, &buf[1], dlen)) {
 
626
                                if ((dlen == cn->length-1) &&
 
627
                                        !strncasecmp(domain, (char *) &cn->data[1], dlen)) {
614
628
                                        ret = LDAP_SUCCESS;
615
629
                                }
616
630
                        }
618
632
 
619
633
                if( ret == LDAP_LOCAL_ERROR ) {
620
634
                        Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
621
 
                                "common name in certificate (%s).\n", 
622
 
                                name, buf, 0 );
 
635
                                "common name in certificate (%.*s).\n", 
 
636
                                name, cn->length, cn->data );
623
637
                        ret = LDAP_CONNECT_ERROR;
624
638
                        if ( ld->ld_error ) {
625
639
                                LDAP_FREE( ld->ld_error );