initial support for SASL

This commit is contained in:
Ralf Haferkamp 2007-12-20 12:33:48 +00:00
parent c677b95768
commit ba0cd79651
14 changed files with 374 additions and 82 deletions

View File

@ -24,15 +24,20 @@
using namespace std;
LDAPAsynConnection::LDAPAsynConnection(const string& hostname, int port,
LDAPAsynConnection::LDAPAsynConnection(const string& url, int port,
LDAPConstraints *cons ){
DEBUG(LDAP_DEBUG_CONSTRUCT,"LDAPAsynConnection::LDAPAsynConnection()"
<< endl);
DEBUG(LDAP_DEBUG_CONSTRUCT | LDAP_DEBUG_PARAMETER,
" host:" << hostname << endl << " port:" << port << endl);
" URL:" << url << endl << " port:" << port << endl);
cur_session=0;
m_constr = 0;
this->init(hostname, port);
// Is this an LDAP URI?
if ( url.find("://") == std::string::npos ) {
this->init(url, port);
} else {
this->initialize(url);
}
this->setConstraints(cons);
}
@ -95,6 +100,41 @@ LDAPMessageQueue* LDAPAsynConnection::bind(const string& dn,
}
}
LDAPMessageQueue* LDAPAsynConnection::saslBind(const std::string &mech,
const std::string &cred,
const LDAPConstraints *cons)
{
DEBUG(LDAP_DEBUG_TRACE, "LDAPAsynConnection::saslBind()" << endl);
LDAPSaslBindRequest *req = new LDAPSaslBindRequest(mech, cred, this, cons);
try{
LDAPMessageQueue *ret = req->sendRequest();
return ret;
}catch(LDAPException e){
delete req;
throw;
}
}
LDAPMessageQueue* LDAPAsynConnection::saslInteractiveBind(
const std::string &mech,
int flags,
SaslInteractionHandler *sih,
const LDAPConstraints *cons)
{
DEBUG(LDAP_DEBUG_TRACE, "LDAPAsynConnection::saslInteractiveBind"
<< std::endl);
LDAPSaslInteractiveBind *req =
new LDAPSaslInteractiveBind(mech, flags, sih, this, cons);
try {
LDAPMessageQueue *ret = req->sendRequest();
return ret;
}catch(LDAPException e){
delete req;
throw;
}
}
LDAPMessageQueue* LDAPAsynConnection::search(const string& base,int scope,
const string& filter,
const StringList& attrs,

View File

@ -21,6 +21,7 @@
#include <LDAPModList.h>
#include <LDAPUrl.h>
#include <LDAPUrlList.h>
#include <SaslInteractionHandler.h>
//* Main class for an asynchronous LDAP connection
/**
@ -59,9 +60,6 @@ class LDAPAsynConnection{
* Search
*/
static const int SEARCH_SUB=2;
// static const int SEARCH_SUB=LDAP_SCOPE_SUBTREE;
// static const int SEARCH_ONE=LDAP_SCOPE_ONELEVEL;
// static const int SEARCH_SUB=LDAP_SCOPE_SUBTREE;
/** Construtor that initializes a connection to a server
* @param hostname Name (or IP-Adress) of the destination host
@ -69,7 +67,7 @@ class LDAPAsynConnection{
* @param cons Default constraints to use with operations over
* this connection
*/
LDAPAsynConnection(const std::string& hostname=std::string("localhost"),
LDAPAsynConnection(const std::string& url=std::string("localhost"),
int port=0, LDAPConstraints *cons=new LDAPConstraints() );
//* Destructor
@ -116,7 +114,17 @@ class LDAPAsynConnection{
* @param dn the distiguished name to bind as
* @param passwd cleartext password to use
*/
LDAPMessageQueue* bind(const std::string& dn="", const std::string& passwd="",
LDAPMessageQueue* bind(const std::string& dn="",
const std::string& passwd="",
const LDAPConstraints *cons=0);
LDAPMessageQueue* saslBind(const std::string& mech,
const std::string& cred,
const LDAPConstraints *cons=0);
LDAPMessageQueue* saslInteractiveBind(const std::string& mech,
int flags=0,
SaslInteractionHandler *sih=0,
const LDAPConstraints *cons=0);
/** Performing a search on a directory tree.

View File

@ -9,8 +9,11 @@
#include "LDAPBindRequest.h"
#include "LDAPException.h"
#include "SaslInteractionHandler.h"
#include "SaslInteraction.h"
#include <cstdlib>
#include <sasl/sasl.h>
using namespace std;
@ -73,10 +76,97 @@ LDAPMessageQueue* LDAPBindRequest::sendRequest(){
}
}
LDAPRequest* LDAPBindRequest::followReferral(LDAPMsg* /*urls*/){
DEBUG(LDAP_DEBUG_TRACE,"LDAPBindRequest::followReferral()" << endl);
DEBUG(LDAP_DEBUG_TRACE,
"ReferralChasing for bind-operation not implemented yet" << endl);
return 0;
LDAPSaslBindRequest::LDAPSaslBindRequest(const std::string& mech,
const std::string& cred,
LDAPAsynConnection *connect,
const LDAPConstraints *cons,
bool isReferral) : LDAPRequest(connect, cons, isReferral),m_mech(mech), m_cred(cred) {}
LDAPMessageQueue* LDAPSaslBindRequest::sendRequest()
{
DEBUG(LDAP_DEBUG_TRACE,"LDAPSaslBindRequest::sendRequest()" << endl);
int msgID=0;
BerValue tmpcred;
tmpcred.bv_val = (char*) malloc( m_cred.size() * sizeof(char));
m_cred.copy(tmpcred.bv_val,string::npos);
tmpcred.bv_len = m_cred.size();
LDAPControl** tmpSrvCtrls=m_cons->getSrvCtrlsArray();
LDAPControl** tmpClCtrls=m_cons->getClCtrlsArray();
int err=ldap_sasl_bind(m_connection->getSessionHandle(), "", m_mech.c_str(),
&tmpcred, tmpSrvCtrls, tmpClCtrls, &msgID);
LDAPControlSet::freeLDAPControlArray(tmpSrvCtrls);
LDAPControlSet::freeLDAPControlArray(tmpClCtrls);
free(tmpcred.bv_val);
if(err != LDAP_SUCCESS){
throw LDAPException(err);
}else{
m_msgID=msgID;
return new LDAPMessageQueue(this);
}
}
LDAPSaslBindRequest::~LDAPSaslBindRequest()
{
DEBUG(LDAP_DEBUG_DESTROY,"LDAPSaslBindRequest::~LDAPSaslBindRequest()" << endl);
}
LDAPSaslInteractiveBind::LDAPSaslInteractiveBind( const std::string& mech,
int flags, SaslInteractionHandler *sih, LDAPAsynConnection *connect,
const LDAPConstraints *cons, bool isReferral) :
LDAPRequest(connect, cons, isReferral),
m_mech(mech), m_flags(flags), m_sih(sih), m_res(0)
{
}
static int my_sasl_interact(LDAP *l, unsigned flags, void *cbh, void *interact)
{
DEBUG(LDAP_DEBUG_TRACE, "LDAPSaslInteractiveBind::my_sasl_interact()"
<< std::endl );
std::list<SaslInteraction*> interactions;
sasl_interact_t *iter = (sasl_interact_t*) interact;
while ( iter->id != SASL_CB_LIST_END ) {
SaslInteraction *si = new SaslInteraction(iter);
interactions.push_back( si );
iter++;
}
((SaslInteractionHandler*)cbh)->handleInteractions(interactions);
return LDAP_SUCCESS;
}
/* This kind of fakes an asynchronous operation, ldap_sasl_interactive_bind_s
* is synchronous */
LDAPMessageQueue *LDAPSaslInteractiveBind::sendRequest()
{
DEBUG(LDAP_DEBUG_TRACE, "LDAPSaslInteractiveBind::sendRequest()" <<
m_mech << std::endl);
LDAPControl** tmpSrvCtrls=m_cons->getSrvCtrlsArray();
LDAPControl** tmpClCtrls=m_cons->getClCtrlsArray();
int res = ldap_sasl_interactive_bind_s( m_connection->getSessionHandle(),
"", m_mech.c_str(), tmpSrvCtrls, tmpClCtrls, m_flags,
my_sasl_interact, m_sih );
DEBUG(LDAP_DEBUG_TRACE, "ldap_sasl_interactive_bind_s returned: "
<< res << std::endl);
if(res != LDAP_SUCCESS){
throw LDAPException(res);
} else {
m_res = new LDAPResult(LDAPMsg::BIND_RESPONSE, res, "");
}
return new LDAPMessageQueue(this);
}
LDAPMsg* LDAPSaslInteractiveBind::getNextMessage() const
{
return m_res;
}
LDAPSaslInteractiveBind::~LDAPSaslInteractiveBind()
{
DEBUG(LDAP_DEBUG_DESTROY,"LDAPSaslInteractiveBind::~LDAPSaslInteractiveBind()" << endl);
}

View File

@ -7,6 +7,8 @@
#define LDAP_BIND_REQUEST_H
#include <LDAPRequest.h>
#include <LDAPResult.h>
#include <SaslInteractionHandler.h>
class LDAPBindRequest : LDAPRequest {
private:
@ -15,14 +17,44 @@ class LDAPBindRequest : LDAPRequest {
std::string m_mech;
public:
LDAPBindRequest(const LDAPBindRequest& req);
LDAPBindRequest( const LDAPBindRequest& req);
//just for simple authentication
LDAPBindRequest(const std::string&, const std::string& passwd,
LDAPAsynConnection *connect, const LDAPConstraints *cons,
bool isReferral=false);
virtual ~LDAPBindRequest();
virtual LDAPMessageQueue *sendRequest();
virtual LDAPRequest* followReferral(LDAPMsg* urls);
};
class LDAPSaslBindRequest : LDAPRequest
{
public:
LDAPSaslBindRequest( const std::string& mech, const std::string& cred,
LDAPAsynConnection *connect, const LDAPConstraints *cons,
bool isReferral=false);
virtual LDAPMessageQueue *sendRequest();
virtual ~LDAPSaslBindRequest();
private:
std::string m_mech;
std::string m_cred;
};
class LDAPSaslInteractiveBind : LDAPRequest
{
public:
LDAPSaslInteractiveBind( const std::string& mech, int flags,
SaslInteractionHandler *sih, LDAPAsynConnection *connect,
const LDAPConstraints *cons, bool isReferral=false);
virtual LDAPMessageQueue *sendRequest();
virtual LDAPMsg* getNextMessage() const;
virtual ~LDAPSaslInteractiveBind();
private:
std::string m_mech;
int m_flags;
SaslInteractionHandler *m_sih;
LDAPResult *m_res;
};
#endif //LDAP_BIND_REQUEST_H

View File

@ -8,6 +8,7 @@
#include "LDAPResult.h"
#include "LDAPExtResult.h"
#include "LDAPSaslBindResult.h"
#include "LDAPRequest.h"
#include "LDAPSearchResult.h"
#include "LDAPSearchReference.h"
@ -22,6 +23,13 @@ LDAPMsg::LDAPMsg(LDAPMessage *msg){
m_hasControls=false;
}
LDAPMsg::LDAPMsg(int type, int id=0){
DEBUG(LDAP_DEBUG_CONSTRUCT,"LDAPMsg::LDAPMsg()" << endl);
msgType = type;
msgID = id;
m_hasControls=false;
}
LDAPMsg* LDAPMsg::create(const LDAPRequest *req, LDAPMessage *msg){
DEBUG(LDAP_DEBUG_TRACE,"LDAPMsg::create()" << endl);
switch(ldap_msgtype(msg)){
@ -34,6 +42,8 @@ LDAPMsg* LDAPMsg::create(const LDAPRequest *req, LDAPMessage *msg){
case EXTENDED_RESPONSE :
return new LDAPExtResult(req,msg);
break;
case BIND_RESPONSE :
return new LDAPSaslBindResult(req,msg);
default :
return new LDAPResult(req, msg);
}

View File

@ -98,6 +98,7 @@ class LDAPMsg{
* Only for internal use.
*/
LDAPMsg(LDAPMessage *msg);
LDAPMsg(int msgType, int msgID);
/**
* This attribute stores Server-Control that were returned with the

View File

@ -70,6 +70,13 @@ LDAPMsg* LDAPRequest::getNextMessage() const
}
}
LDAPRequest* LDAPRequest::followReferral(LDAPMsg* /*urls*/){
DEBUG(LDAP_DEBUG_TRACE,"LDAPBindRequest::followReferral()" << endl);
DEBUG(LDAP_DEBUG_TRACE,
"ReferralChasing not implemented for this operation" << endl);
return 0;
}
const LDAPConstraints* LDAPRequest::getConstraints() const{
DEBUG(LDAP_DEBUG_TRACE,"LDAPRequest::getConstraints()" << endl);
return m_cons;

View File

@ -40,7 +40,7 @@ class LDAPRequest{
const LDAPConstraints* getConstraints() const;
const LDAPAsynConnection* getConnection() const;
LDAPMsg *getNextMessage() const;
virtual LDAPMsg *getNextMessage() const;
int getType()const;
int getMsgID() const;
int getHopCount() const;
@ -64,7 +64,7 @@ class LDAPRequest{
* functions of the C-API to send the Request to a LDAP-Server
*/
virtual LDAPMessageQueue* sendRequest()=0;
virtual LDAPRequest* followReferral(LDAPMsg* ref)=0;
virtual LDAPRequest* followReferral(LDAPMsg* ref);
/**
* Compare this request with another on. And returns true if they

View File

@ -53,6 +53,11 @@ LDAPResult::LDAPResult(const LDAPRequest *req, LDAPMessage *msg) :
}
}
LDAPResult::LDAPResult(int type, int resultCode, const std::string &msg) :
LDAPMsg(type,0), m_resCode(resultCode), m_errMsg(msg)
{}
LDAPResult::~LDAPResult(){
DEBUG(LDAP_DEBUG_DESTROY,"LDAPResult::~LDAPResult()" << endl);
}

View File

@ -103,6 +103,7 @@ class LDAPResult : public LDAPMsg{
* Message.
*/
LDAPResult(const LDAPRequest *req, LDAPMessage *msg);
LDAPResult(int type, int resultCode, const std::string &msg);
/**
* The destructor.

View File

@ -0,0 +1,44 @@
/*
* Copyright 2007, OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "debug.h"
#include <lber.h>
#include "LDAPRequest.h"
#include "LDAPException.h"
#include "LDAPResult.h"
#include "LDAPSaslBindResult.h"
using namespace std;
LDAPSaslBindResult::LDAPSaslBindResult(const LDAPRequest* req, LDAPMessage* msg) :
LDAPResult(req, msg){
DEBUG(LDAP_DEBUG_CONSTRUCT,"LDAPSaslBindResult::LDAPSaslBindResult()"
<< std::endl);
BerValue* data = 0;
LDAP* lc = req->getConnection()->getSessionHandle();
int err = ldap_parse_sasl_bind_result(lc, msg, &data, 0);
if( err != LDAP_SUCCESS && err != LDAP_SASL_BIND_IN_PROGRESS ){
ber_bvfree(data);
throw LDAPException(err);
}else{
if(data){
DEBUG(LDAP_DEBUG_TRACE, " creds present" << std::endl);
m_creds=string(data->bv_val, data->bv_len);
ber_bvfree(data);
} else {
DEBUG(LDAP_DEBUG_TRACE, " no creds present" << std::endl);
}
}
}
LDAPSaslBindResult::~LDAPSaslBindResult(){
DEBUG(LDAP_DEBUG_DESTROY,"LDAPSaslBindResult::~LDAPSaslBindResult()" << endl);
}
const string& LDAPSaslBindResult::getServerCreds() const{
return m_creds;
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2007, OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#ifndef LDAP_SASL_BIND_RESULT_H
#define LDAP_SASL_BIND_RESULT_H
#include <ldap.h>
#include <LDAPResult.h>
class LDAPRequest;
/**
* Object of this class are created by the LDAPMsg::create method if
* results for an Extended Operation were returned by a LDAP server.
*/
class LDAPSaslBindResult : public LDAPResult {
public :
/**
* Constructor that creates an LDAPExtResult-object from the C-API
* structures
*/
LDAPSaslBindResult(const LDAPRequest* req, LDAPMessage* msg);
/**
* The Destructor
*/
virtual ~LDAPSaslBindResult();
/**
* @returns If the result contained data this method will return
* the data to the caller as a std::string.
*/
const std::string& getServerCreds() const;
private:
std::string m_creds;
};
#endif // LDAP_SASL_BIND_RESULT_H

View File

@ -6,73 +6,79 @@
lib_LTLIBRARIES = libldapcpp.la
libldapcpp_la_SOURCES = LDAPAddRequest.cpp \
LDAPAsynConnection.cpp \
LDAPAttribute.cpp \
LDAPAttributeList.cpp \
LDAPAttrType.cpp \
LDAPBindRequest.cpp \
LDAPCompareRequest.cpp \
LDAPConnection.cpp \
LDAPConstraints.cpp \
LDAPControl.cpp \
LDAPControlSet.cpp \
LDAPDeleteRequest.cpp \
LDAPEntry.cpp \
LDAPEntryList.cpp \
LDAPException.cpp \
LDAPExtRequest.cpp \
LDAPExtResult.cpp \
LDAPMessage.cpp \
LDAPMessageQueue.cpp \
LDAPModDNRequest.cpp \
LDAPModification.cpp \
LDAPModifyRequest.cpp \
LDAPModList.cpp \
LDAPObjClass.cpp \
LDAPRebind.cpp \
LDAPRebindAuth.cpp \
LDAPReferralException.cpp \
LDAPReferenceList.cpp \
LDAPRequest.cpp \
LDAPResult.cpp \
LDAPSchema.cpp \
LDAPSearchReference.cpp \
LDAPSearchRequest.cpp \
LDAPSearchResult.cpp \
LDAPSearchResults.cpp \
LDAPUrl.cpp \
LDAPUrlList.cpp \
StringList.cpp
LDAPAsynConnection.cpp \
LDAPAttribute.cpp \
LDAPAttributeList.cpp \
LDAPAttrType.cpp \
LDAPBindRequest.cpp \
LDAPCompareRequest.cpp \
LDAPConnection.cpp \
LDAPConstraints.cpp \
LDAPControl.cpp \
LDAPControlSet.cpp \
LDAPDeleteRequest.cpp \
LDAPEntry.cpp \
LDAPEntryList.cpp \
LDAPException.cpp \
LDAPExtRequest.cpp \
LDAPExtResult.cpp \
LDAPMessage.cpp \
LDAPMessageQueue.cpp \
LDAPModDNRequest.cpp \
LDAPModification.cpp \
LDAPModifyRequest.cpp \
LDAPModList.cpp \
LDAPObjClass.cpp \
LDAPRebind.cpp \
LDAPRebindAuth.cpp \
LDAPReferralException.cpp \
LDAPReferenceList.cpp \
LDAPRequest.cpp \
LDAPResult.cpp \
LDAPSaslBindResult.cpp \
LDAPSchema.cpp \
LDAPSearchReference.cpp \
LDAPSearchRequest.cpp \
LDAPSearchResult.cpp \
LDAPSearchResults.cpp \
LDAPUrl.cpp \
LDAPUrlList.cpp \
SaslInteraction.cpp \
SaslInteractionHandler.cpp \
StringList.cpp
include_HEADERS = LDAPAsynConnection.h \
LDAPAttribute.h \
LDAPAttributeList.h \
LDAPAttrType.h \
LDAPConnection.h \
LDAPConstraints.h \
LDAPControl.h \
LDAPControlSet.h \
LDAPEntry.h \
LDAPEntryList.h \
LDAPException.h \
LDAPExtResult.h \
LDAPMessage.h \
LDAPMessageQueue.h \
LDAPModification.h \
LDAPModList.h \
LDAPObjClass.h \
LDAPRebind.h \
LDAPRebindAuth.h \
LDAPReferralException.h \
LDAPReferenceList.h \
LDAPResult.h \
LDAPSchema.h \
LDAPSearchReference.h \
LDAPSearchResult.h \
LDAPSearchResults.h \
LDAPUrl.h \
LDAPUrlList.h \
StringList.h
LDAPAttribute.h \
LDAPAttributeList.h \
LDAPAttrType.h \
LDAPConnection.h \
LDAPConstraints.h \
LDAPControl.h \
LDAPControlSet.h \
LDAPEntry.h \
LDAPEntryList.h \
LDAPException.h \
LDAPExtResult.h \
LDAPMessage.h \
LDAPMessageQueue.h \
LDAPModification.h \
LDAPModList.h \
LDAPObjClass.h \
LDAPRebind.h \
LDAPRebindAuth.h \
LDAPReferralException.h \
LDAPReferenceList.h \
LDAPResult.h \
LDAPSaslBindResult.h \
LDAPSchema.h \
LDAPSearchReference.h \
LDAPSearchResult.h \
LDAPSearchResults.h \
LDAPUrl.h \
LDAPUrlList.h \
SaslInteraction.h \
SaslInteractionHandler.h \
StringList.h
noinst_HEADERS = LDAPAddRequest.h \
LDAPBindRequest.h \

View File

@ -6,6 +6,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <ldap.h> header file. */
#undef HAVE_LDAP_H
/* Define to 1 if you have the `resolv' library (-lresolv). */
#undef HAVE_LIBRESOLV
@ -30,6 +33,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H