Skip to content

Commit

Permalink
Ticket 47531 - Mozldap - need to rewrite sasl_io_recv
Browse files Browse the repository at this point in the history
Bug Description:  Mozldap does not have some "ber" functions (ber_skip_element) that
                  are in openldap.  This causes the build to fail.

Fix Description:  To parse the ber we need a local copy of the ber structure(which I
                  called MozElement), so that the ber_ptr can be manipulated.  I had to
                  use a new header file(mozldap.h), because the mozldap BerElement typedef's
                  caused build failures.

                  There is also a mozldap version check, and if the verison is newer than
                  what was used for mozldap.h, the build will fail.  The current internal
                  version is 604, even though the rpm says 605.

https://fedorahosted.org/389/ticket/47531

Reviewed by: richm(Thanks!)
  • Loading branch information
mreynolds389 committed Oct 3, 2013
1 parent 92f9e83 commit 62c89ea
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 3 deletions.
45 changes: 45 additions & 0 deletions ldap/servers/slapd/mozldap.h
@@ -0,0 +1,45 @@
/*
* mozldap does not have all the openldap "ber" functions, like ber_skip_element.
* So we need to directly parse the ber element, and see inside the ber struct.
* From lber-int.h
*/
typedef struct seqorset {
ber_len_t sos_clen;
ber_tag_t sos_tag;
char *sos_first;
char *sos_ptr;
struct seqorset *sos_next;
} Seqorset;

#define SOS_STACK_SIZE 8 /* depth of the pre-allocated sos structure stack */
#define MAX_TAG_SIZE (1 + sizeof(ber_int_t)) /* One byte for the length of the tag */
#define MAX_LEN_SIZE (1 + sizeof(ber_int_t)) /* One byte for the length of the length */
#define MAX_VALUE_PREFIX_SIZE (2 + sizeof(ber_int_t)) /* 1 byte for the tag and 1 for the len (msgid) */
#define BER_ARRAY_QUANTITY 7 /* 0:Tag 1:Length 2:Value-prefix 3:Value 4:Value-suffix */

struct berelement {
ldap_x_iovec ber_struct[BER_ARRAY_QUANTITY]; /* See above */
char ber_tag_contents[MAX_TAG_SIZE];
char ber_len_contents[MAX_LEN_SIZE];
char ber_pre_contents[MAX_VALUE_PREFIX_SIZE];
char ber_suf_contents[MAX_LEN_SIZE+1];
char *ber_buf; /* update the value value when writing in case realloc is called */
char *ber_ptr;
char *ber_end;
struct seqorset *ber_sos;
ber_len_t ber_tag_len_read;
ber_tag_t ber_tag; /* Remove me someday */
ber_len_t ber_len; /* Remove me someday */
int ber_usertag;
char ber_options;
char *ber_rwptr;
BERTranslateProc ber_encode_translate_proc;
BERTranslateProc ber_decode_translate_proc;
int ber_flags;
#define LBER_FLAG_NO_FREE_BUFFER 1 /* don't free ber_buf */
unsigned int ber_buf_reallocs; /* realloc counter */
int ber_sos_stack_posn;
Seqorset ber_sos_stack[SOS_STACK_SIZE];
};
typedef struct berelement MozElement;

39 changes: 36 additions & 3 deletions ldap/servers/slapd/sasl_io.c
Expand Up @@ -45,6 +45,14 @@
#include "fe.h"
#include <sasl.h>
#include <arpa/inet.h>
#ifndef USE_OPENLDAP
#include "mozldap.h"
#if LDAP_VENDOR_VERSION > 604
/* garbage to cause build to fail */
MOZLDAP is newer than expected, if the ber structure has not changed
(see ldap/server/slapd/mozldap.h), please bump the version number(604 -> new version)
#endif
#endif

/*
* I/O Shim Layer for SASL Encryption
Expand Down Expand Up @@ -261,11 +269,16 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt
* Check if an LDAP operation was sent unencrypted
*/
if(!sp->send_encrypted && *sp->encrypted_buffer == LDAP_TAG_MESSAGE){
struct berval bv, tmp_bv;
struct berval bv;
#ifdef USE_OPENLDAP
BerElement *ber = NULL;
struct berval tmp_bv;
#else
MozElement *ber = NULL;
#endif
ber_len_t maxbersize = config_get_maxbersize();
ber_len_t ber_len = 0;
ber_tag_t tag;
ber_tag_t tag = 0;

slapi_log_error( SLAPI_LOG_CONNS, "sasl_io_start_packet", "conn=%" NSPRIu64 " fd=%d "
"Sent an LDAP message that was not encrypted.\n", (long long unsigned int)c->c_connid,
Expand Down Expand Up @@ -340,24 +353,40 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt
*/
bv.bv_val = sp->encrypted_buffer;
bv.bv_len = sp->encrypted_buffer_offset;

#ifdef USE_OPENLDAP
if ( (ber = ber_init(&bv)) == NULL){
#else
if ( (ber = (MozElement *)ber_init(&bv)) == NULL){
#endif
goto done;
}

/*
* Start parsing the berElement. First skip this tag, and move on to the
* tag msgid
*/
#ifdef USE_OPENLDAP
ber_skip_tag(ber, &ber_len);
if( ber_peek_tag( ber, &ber_len ) == LDAP_TAG_MSGID) {
#else
ber_skip_tag((BerElement*)ber, &ber_len);
if( ber_peek_tag( (BerElement*)ber, &ber_len ) == LDAP_TAG_MSGID) {
#endif
/*
* Skip the entire msgid element, so we can get to the LDAP op tag
*/
#ifdef USE_OPENLDAP
if(ber_skip_element(ber, &tmp_bv) == LDAP_TAG_MSGID) {
/*
* We only allow unbind operations to be processed for unencrypted operations
*/
if (( tag = ber_peek_tag( ber, &ber_len )) == LDAP_REQ_UNBIND ) {
#else
{
tag = *ber->ber_ptr++;
if (*ber->ber_ptr == LDAP_REQ_UNBIND){
#endif
slapi_log_error( SLAPI_LOG_CONNS, "sasl_io_start_packet", "conn=%" NSPRIu64 " fd=%d "
"Received unencrypted UNBIND operation.\n", (long long unsigned int)c->c_connid,
c->c_sd);
Expand All @@ -368,7 +397,11 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt
}
slapi_log_error( SLAPI_LOG_CONNS, "sasl_io_start_packet", "conn=%" NSPRIu64 " fd=%d "
"Error: received an LDAP message (tag 0x%lx) that was not encrypted.\n",
(long long unsigned int)c->c_connid, c->c_sd, tag);
#ifdef USE_OPENLDAP
(long long unsigned int)c->c_connid, c->c_sd, (long unsigned int)tag);
#else
(long long unsigned int)c->c_connid, c->c_sd, (long unsigned int)*ber->ber_ptr);
#endif
}
}

Expand Down

0 comments on commit 62c89ea

Please sign in to comment.