Back to index

openldap  2.4.31
Classes | Defines | Typedefs | Functions | Variables
tls2.c File Reference
#include "portable.h"
#include "ldap_config.h"
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/errno.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/ctype.h>
#include <ac/time.h>
#include <ac/unistd.h>
#include <ac/param.h>
#include <ac/dirent.h>
#include "ldap-int.h"

Go to the source code of this file.

Classes

struct  oid_name

Defines

#define LBER_TAG_OID   ((ber_tag_t) 0x06UL)
#define LBER_TAG_UTF8   ((ber_tag_t) 0x0cUL)
#define LBER_TAG_PRINTABLE   ((ber_tag_t) 0x13UL)
#define LBER_TAG_TELETEX   ((ber_tag_t) 0x14UL)
#define LBER_TAG_IA5   ((ber_tag_t) 0x16UL)
#define LBER_TAG_UNIVERSAL   ((ber_tag_t) 0x1cUL)
#define LBER_TAG_BMP   ((ber_tag_t) 0x1eUL)
#define BITS_PER_BYTE   8
#define SQUOTE_LENGTH   1
#define B_CHAR_LENGTH   1
#define STR_OVERHEAD   (2*SQUOTE_LENGTH + B_CHAR_LENGTH)

Typedefs

typedef struct oid_name oid_name

Functions

int ldap_start_tls (LDAP *ld, LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp)
int ldap_install_tls (LDAP *ld)
int ldap_start_tls_s (LDAP *ld, LDAPControl **serverctrls, LDAPControl **clientctrls)
static oid_namefind_oid (struct berval *oid)
static int der_to_ldap_BitString (struct berval *berValue, struct berval *ldapValue)
int ldap_X509dn2bv (void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func, unsigned flags)

Variables

static oid_name oids []

Class Documentation

struct oid_name

Definition at line 49 of file tls2.c.


Define Documentation

#define B_CHAR_LENGTH   1

Definition at line 990 of file tls2.c.

#define BITS_PER_BYTE   8

Definition at line 988 of file tls2.c.

#define LBER_TAG_BMP   ((ber_tag_t) 0x1eUL)

Definition at line 965 of file tls2.c.

#define LBER_TAG_IA5   ((ber_tag_t) 0x16UL)

Definition at line 963 of file tls2.c.

#define LBER_TAG_OID   ((ber_tag_t) 0x06UL)

Definition at line 953 of file tls2.c.

#define LBER_TAG_PRINTABLE   ((ber_tag_t) 0x13UL)

Definition at line 961 of file tls2.c.

#define LBER_TAG_TELETEX   ((ber_tag_t) 0x14UL)

Definition at line 962 of file tls2.c.

#define LBER_TAG_UNIVERSAL   ((ber_tag_t) 0x1cUL)

Definition at line 964 of file tls2.c.

#define LBER_TAG_UTF8   ((ber_tag_t) 0x0cUL)

Definition at line 960 of file tls2.c.

#define SQUOTE_LENGTH   1

Definition at line 989 of file tls2.c.

Definition at line 991 of file tls2.c.


Typedef Documentation

typedef struct oid_name oid_name

Function Documentation

static int der_to_ldap_BitString ( struct berval berValue,
struct berval ldapValue 
) [static]

Definition at line 994 of file tls2.c.

{
       ber_len_t bitPadding=0;
       ber_len_t bits, maxBits;
       char *tmpStr;
       unsigned char byte;
       ber_len_t bitLength;
       ber_len_t valLen;
       unsigned char* valPtr;

       ldapValue->bv_len=0;
       ldapValue->bv_val=NULL;

       /* Gets padding and points to binary data */
       valLen=berValue->bv_len;
       valPtr=(unsigned char*)berValue->bv_val;
       if (valLen) {
              bitPadding=(ber_len_t)(valPtr[0]);
              valLen--;
              valPtr++;
       }
       /* If Block is non DER encoding fixes to DER encoding */
       if (bitPadding >= BITS_PER_BYTE) {
              if (valLen*BITS_PER_BYTE > bitPadding ) {
                     valLen-=(bitPadding/BITS_PER_BYTE);
                     bitPadding%=BITS_PER_BYTE;
              } else {
                     valLen=0;
                     bitPadding=0;
              }
       }
       /* Just in case bad encoding */
       if (valLen*BITS_PER_BYTE < bitPadding ) {
              bitPadding=0;
              valLen=0;
       }

       /* Gets buffer to hold RFC4517 Bit String format */
       bitLength=valLen*BITS_PER_BYTE-bitPadding;
       tmpStr=LDAP_MALLOC(bitLength + STR_OVERHEAD + 1);

       if (!tmpStr)
              return LDAP_NO_MEMORY;

       ldapValue->bv_val=tmpStr;
       ldapValue->bv_len=bitLength + STR_OVERHEAD;

       /* Formatting in '*binary-digit'B format */
       maxBits=BITS_PER_BYTE;
       *tmpStr++ ='\'';
       while(valLen) {
              byte=*valPtr;
              if (valLen==1)
                     maxBits-=bitPadding;
              for (bits=0; bits<maxBits; bits++) {
                     if (0x80 & byte)
                            *tmpStr='1';
                     else
                            *tmpStr='0';
                     tmpStr++;
                     byte<<=1;
              }
              valPtr++;
              valLen--;
       }
       *tmpStr++ ='\'';
       *tmpStr++ ='B';
       *tmpStr=0;

       return LDAP_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static oid_name* find_oid ( struct berval oid) [static]

Definition at line 968 of file tls2.c.

{
       int i;

       for ( i=0; !BER_BVISNULL( &oids[i].oid ); i++ ) {
              if ( oids[i].oid.bv_len != oid->bv_len ) continue;
              if ( !strcmp( oids[i].oid.bv_val, oid->bv_val ))
                     return &oids[i];
       }
       return NULL;
}

Here is the caller graph for this function:

int ldap_install_tls ( LDAP *  ld)

Definition at line 898 of file tls2.c.

{
#ifndef HAVE_TLS
       return LDAP_NOT_SUPPORTED;
#else
       if ( ldap_tls_inplace( ld ) ) {
              return LDAP_LOCAL_ERROR;
       }

       return ldap_int_tls_start( ld, ld->ld_defconn, NULL );
#endif
}

Here is the caller graph for this function:

int ldap_start_tls ( LDAP *  ld,
LDAPControl **  serverctrls,
LDAPControl **  clientctrls,
int msgidp 
)

Definition at line 888 of file tls2.c.

{
       return ldap_extended_operation( ld, LDAP_EXOP_START_TLS,
              NULL, serverctrls, clientctrls, msgidp );
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ldap_start_tls_s ( LDAP *  ld,
LDAPControl **  serverctrls,
LDAPControl **  clientctrls 
)

Definition at line 912 of file tls2.c.

{
#ifndef HAVE_TLS
       return LDAP_NOT_SUPPORTED;
#else
       int rc;
       char *rspoid = NULL;
       struct berval *rspdata = NULL;

       /* XXYYZ: this initiates operation only on default connection! */

       if ( ldap_tls_inplace( ld ) ) {
              return LDAP_LOCAL_ERROR;
       }

       rc = ldap_extended_operation_s( ld, LDAP_EXOP_START_TLS,
              NULL, serverctrls, clientctrls, &rspoid, &rspdata );

       if ( rspoid != NULL ) {
              LDAP_FREE(rspoid);
       }

       if ( rspdata != NULL ) {
              ber_bvfree( rspdata );
       }

       if ( rc == LDAP_SUCCESS ) {
              rc = ldap_int_tls_start( ld, ld->ld_defconn, NULL );
       }

       return rc;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ldap_X509dn2bv ( void x509_name,
struct berval bv,
LDAPDN_rewrite_func *  func,
unsigned  flags 
)

Definition at line 1076 of file tls2.c.

{
       LDAPDN newDN;
       LDAPRDN       newRDN;
       LDAPAVA *newAVA, *baseAVA;
       BerElementBuffer berbuf;
       BerElement *ber = (BerElement *)&berbuf;
       char oids[8192], *oidptr = oids, *oidbuf = NULL;
       void *ptrs[2048];
       char *dn_end, *rdn_end;
       int i, navas, nrdns, rc = LDAP_SUCCESS;
       size_t dnsize, oidrem = sizeof(oids), oidsize = 0;
       int csize;
       ber_tag_t tag;
       ber_len_t len;
       oid_name *oidname;

       struct berval Oid, Val, oid2, *in = x509_name;

       assert( bv != NULL );

       bv->bv_len = 0;
       bv->bv_val = NULL;

       navas = 0;
       nrdns = 0;

       /* A DN is a SEQUENCE of RDNs. An RDN is a SET of AVAs.
        * An AVA is a SEQUENCE of attr and value.
        * Count the number of AVAs and RDNs
        */
       ber_init2( ber, in, LBER_USE_DER );
       tag = ber_peek_tag( ber, &len );
       if ( tag != LBER_SEQUENCE )
              return LDAP_DECODING_ERROR;

       for ( tag = ber_first_element( ber, &len, &dn_end );
              tag == LBER_SET;
              tag = ber_next_element( ber, &len, dn_end )) {
              nrdns++;
              for ( tag = ber_first_element( ber, &len, &rdn_end );
                     tag == LBER_SEQUENCE;
                     tag = ber_next_element( ber, &len, rdn_end )) {
                     tag = ber_skip_tag( ber, &len );
                     ber_skip_data( ber, len );
                     navas++;
              }
       }

       /* Allocate the DN/RDN/AVA stuff as a single block */    
       dnsize = sizeof(LDAPRDN) * (nrdns+1);
       dnsize += sizeof(LDAPAVA *) * (navas+nrdns);
       dnsize += sizeof(LDAPAVA) * navas;
       if (dnsize > sizeof(ptrs)) {
              newDN = (LDAPDN)LDAP_MALLOC( dnsize );
              if ( newDN == NULL )
                     return LDAP_NO_MEMORY;
       } else {
              newDN = (LDAPDN)(char *)ptrs;
       }
       
       newDN[nrdns] = NULL;
       newRDN = (LDAPRDN)(newDN + nrdns+1);
       newAVA = (LDAPAVA *)(newRDN + navas + nrdns);
       baseAVA = newAVA;

       /* Rewind and start extracting */
       ber_rewind( ber );

       tag = ber_first_element( ber, &len, &dn_end );
       for ( i = nrdns - 1; i >= 0; i-- ) {
              newDN[i] = newRDN;

              for ( tag = ber_first_element( ber, &len, &rdn_end );
                     tag == LBER_SEQUENCE;
                     tag = ber_next_element( ber, &len, rdn_end )) {

                     *newRDN++ = newAVA;
                     tag = ber_skip_tag( ber, &len );
                     tag = ber_get_stringbv( ber, &Oid, LBER_BV_NOTERM );
                     if ( tag != LBER_TAG_OID ) {
                            rc = LDAP_DECODING_ERROR;
                            goto nomem;
                     }

                     oid2.bv_val = oidptr;
                     oid2.bv_len = oidrem;
                     if ( ber_decode_oid( &Oid, &oid2 ) < 0 ) {
                            rc = LDAP_DECODING_ERROR;
                            goto nomem;
                     }
                     oidname = find_oid( &oid2 );
                     if ( !oidname ) {
                            newAVA->la_attr = oid2;
                            oidptr += oid2.bv_len + 1;
                            oidrem -= oid2.bv_len + 1;

                            /* Running out of OID buffer space? */
                            if (oidrem < 128) {
                                   if ( oidsize == 0 ) {
                                          oidsize = sizeof(oids) * 2;
                                          oidrem = oidsize;
                                          oidbuf = LDAP_MALLOC( oidsize );
                                          if ( oidbuf == NULL ) goto nomem;
                                          oidptr = oidbuf;
                                   } else {
                                          char *old = oidbuf;
                                          oidbuf = LDAP_REALLOC( oidbuf, oidsize*2 );
                                          if ( oidbuf == NULL ) goto nomem;
                                          /* Buffer moved! Fix AVA pointers */
                                          if ( old != oidbuf ) {
                                                 LDAPAVA *a;
                                                 long dif = oidbuf - old;

                                                 for (a=baseAVA; a<=newAVA; a++){
                                                        if (a->la_attr.bv_val >= old &&
                                                               a->la_attr.bv_val <= (old + oidsize))
                                                               a->la_attr.bv_val += dif;
                                                 }
                                          }
                                          oidptr = oidbuf + oidsize - oidrem;
                                          oidrem += oidsize;
                                          oidsize *= 2;
                                   }
                            }
                     } else {
                            if ( func ) {
                                   newAVA->la_attr = oidname->oid;
                            } else {
                                   newAVA->la_attr = oidname->name;
                            }
                     }
                     newAVA->la_private = NULL;
                     newAVA->la_flags = LDAP_AVA_STRING;
                     tag = ber_get_stringbv( ber, &Val, LBER_BV_NOTERM );
                     switch(tag) {
                     case LBER_TAG_UNIVERSAL:
                            /* This uses 32-bit ISO 10646-1 */
                            csize = 4; goto to_utf8;
                     case LBER_TAG_BMP:
                            /* This uses 16-bit ISO 10646-1 */
                            csize = 2; goto to_utf8;
                     case LBER_TAG_TELETEX:
                            /* This uses 8-bit, assume ISO 8859-1 */
                            csize = 1;
to_utf8:             rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value );
                            newAVA->la_flags |= LDAP_AVA_NONPRINTABLE;
allocd:
                            newAVA->la_flags |= LDAP_AVA_FREE_VALUE;
                            if (rc != LDAP_SUCCESS) goto nomem;
                            break;
                     case LBER_TAG_UTF8:
                            newAVA->la_flags |= LDAP_AVA_NONPRINTABLE;
                            /* This is already in UTF-8 encoding */
                     case LBER_TAG_IA5:
                     case LBER_TAG_PRINTABLE:
                            /* These are always 7-bit strings */
                            newAVA->la_value = Val;
                            break;
                     case LBER_BITSTRING:
                            /* X.690 bitString value converted to RFC4517 Bit String */
                            rc = der_to_ldap_BitString( &Val, &newAVA->la_value );
                            goto allocd;
                     default:
                            /* Not a string type at all */
                            newAVA->la_flags = 0;
                            newAVA->la_value = Val;
                            break;
                     }
                     newAVA++;
              }
              *newRDN++ = NULL;
              tag = ber_next_element( ber, &len, dn_end );
       }
              
       if ( func ) {
              rc = func( newDN, flags, NULL );
              if ( rc != LDAP_SUCCESS )
                     goto nomem;
       }

       rc = ldap_dn2bv_x( newDN, bv, LDAP_DN_FORMAT_LDAPV3, NULL );

nomem:
       for (;baseAVA < newAVA; baseAVA++) {
              if (baseAVA->la_flags & LDAP_AVA_FREE_ATTR)
                     LDAP_FREE( baseAVA->la_attr.bv_val );
              if (baseAVA->la_flags & LDAP_AVA_FREE_VALUE)
                     LDAP_FREE( baseAVA->la_value.bv_val );
       }

       if ( oidsize != 0 )
              LDAP_FREE( oidbuf );
       if ( newDN != (LDAPDN)(char *) ptrs )
              LDAP_FREE( newDN );
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

oid_name oids[] [static]
Initial value:
 {
       { BER_BVC("2.5.4.3"), BER_BVC("cn") },
       { BER_BVC("2.5.4.4"), BER_BVC("sn") },
       { BER_BVC("2.5.4.6"), BER_BVC("c") },
       { BER_BVC("2.5.4.7"), BER_BVC("l") },
       { BER_BVC("2.5.4.8"), BER_BVC("st") },
       { BER_BVC("2.5.4.10"), BER_BVC("o") },
       { BER_BVC("2.5.4.11"), BER_BVC("ou") },
       { BER_BVC("2.5.4.12"), BER_BVC("title") },
       { BER_BVC("2.5.4.41"), BER_BVC("name") },
       { BER_BVC("2.5.4.42"), BER_BVC("givenName") },
       { BER_BVC("2.5.4.43"), BER_BVC("initials") },
       { BER_BVC("2.5.4.44"), BER_BVC("generationQualifier") },
       { BER_BVC("2.5.4.46"), BER_BVC("dnQualifier") },
       { BER_BVC("1.2.840.113549.1.9.1"), BER_BVC("email") },
       { BER_BVC("0.9.2342.19200300.100.1.25"), BER_BVC("dc") },
       { BER_BVNULL, BER_BVNULL }
}

Definition at line 54 of file tls2.c.