From 621d9e5c413e561293d7484b93882d985b3fe15f Mon Sep 17 00:00:00 2001 From: Endi Sukma Dewata Date: Sat, 24 Mar 2012 02:27:47 -0500 Subject: Removed unnecessary pki folder. Previously the source code was located inside a pki folder. This folder was created during svn migration and is no longer needed. This folder has now been removed and the contents have been moved up one level. Ticket #131 --- base/tps/src/authentication/CMakeLists.txt | 52 +++ .../tps/src/authentication/LDAP_Authentication.cpp | 424 +++++++++++++++++++++ 2 files changed, 476 insertions(+) create mode 100644 base/tps/src/authentication/CMakeLists.txt create mode 100644 base/tps/src/authentication/LDAP_Authentication.cpp (limited to 'base/tps/src/authentication') diff --git a/base/tps/src/authentication/CMakeLists.txt b/base/tps/src/authentication/CMakeLists.txt new file mode 100644 index 000000000..ba8ca07dc --- /dev/null +++ b/base/tps/src/authentication/CMakeLists.txt @@ -0,0 +1,52 @@ +project(ldapauth_library CXX) + +set(LDAPAUTH_PUBLIC_INCLUDE_DIRS + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${TPS_INCLUDE_DIR} + CACHE INTERNAL "ldapauth public include directories" +) + +set(LDAPAUTH_PRIVATE_INCLUDE_DIRS + ${LDAPAUTH_PUBLIC_INCLUDE_DIRS} + ${CMAKE_BINARY_DIR} + ${NSPR_INCLUDE_DIRS} + ${NSS_INCLUDE_DIRS} + ${SVRCORE_INCLUDE_DIRS} + ${LDAP_INCLUDE_DIRS} +) + +set(LDAPAUTH_SHARED_LIBRARY + ldapauth_library + CACHE INTERNAL "ldapauth shared library" +) + +set(LDAPAUTH_LINK_LIBRARIES + ${NSPR_LIBRARIES} + ${NSS_LIBRARIES} + ${SVRCORE_LIBRARIES} + ${LDAP_LIBRARIES} + ${TOKENDB_SHARED_LIBRARY} + ${TPS_SHARED_LIBRARY} +) + +set(ldapauth_library_SRCS + LDAP_Authentication.cpp +) + +include_directories(${LDAPAUTH_PRIVATE_INCLUDE_DIRS}) + +add_library(${LDAPAUTH_SHARED_LIBRARY} SHARED ${ldapauth_library_SRCS}) +target_link_libraries(${LDAPAUTH_SHARED_LIBRARY} ${LDAPAUTH_LINK_LIBRARIES}) + +set_target_properties(${LDAPAUTH_SHARED_LIBRARY} + PROPERTIES + OUTPUT_NAME + ldapauth +) + +install( + TARGETS + ${LDAPAUTH_SHARED_LIBRARY} + LIBRARY DESTINATION ${LIB_INSTALL_DIR}/tps +) diff --git a/base/tps/src/authentication/LDAP_Authentication.cpp b/base/tps/src/authentication/LDAP_Authentication.cpp new file mode 100644 index 000000000..3e073dfff --- /dev/null +++ b/base/tps/src/authentication/LDAP_Authentication.cpp @@ -0,0 +1,424 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301 USA +// +// Copyright (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +#include +#include +#include +#include +#include "engine/RA.h" +#include "ldap.h" +#include "authentication/LDAP_Authentication.h" +#include "authentication/Authentication.h" +#include "main/Memory.h" +#include "main/Util.h" + +/** + * Constructs a base processor. + */ +LDAP_Authentication::LDAP_Authentication () +{ + m_hostport = NULL; + m_baseDN = NULL; + m_connInfo = NULL; + m_attributes = NULL; + m_ssl = NULL; + m_bindDN = NULL; + m_bindPwd = NULL; +} + +/** + * Destructs processor. + */ +LDAP_Authentication::~LDAP_Authentication () +{ + if( m_hostport != NULL ) { + PL_strfree( m_hostport ); + m_hostport = NULL; + } + + if( m_baseDN != NULL ) { + PL_strfree( m_baseDN ); + m_baseDN = NULL; + } + + if( m_connInfo != NULL ) { + delete m_connInfo; + m_connInfo = NULL; + } +} + +/* + * Search for password name "name" in the password file "filepath" + */ +static char *get_pwd_from_conf(char *filepath, const char *name) +{ + PRFileDesc *fd; + char line[1024]; + int removed_return; + char *val= NULL; + + fd= PR_Open(filepath, PR_RDONLY, 400); + if (fd == NULL) { + return NULL; + } + + while (1) { + int n = Util::ReadLine(fd, line, 1024, &removed_return); + if (n > 0) { + /* handle comment line */ + if (line[0] == '#') + continue; + int c = 0; + while ((c < n) && (line[c] != ':')) { + c++; + } + if (c < n) { + line[c] = '\0'; + } else { + continue; /* no ':', skip this line */ + } + if (!PL_strcmp (line, name)) { + val = PL_strdup(&line[c+1]); + break; + } + } else if (n == 0 && removed_return == 1) { + continue; /* skip empty line */ + } else { + break; + } + } + if( fd != NULL ) { + PR_Close( fd ); + fd = NULL; + } + return val; + +} + +void LDAP_Authentication::Initialize(int instanceIndex) { + char configname[256]; + const char *prefix="auth.instance"; + + m_index = instanceIndex; + PR_snprintf((char *)configname, 256, "%s.%d.hostport", prefix, instanceIndex); + m_hostport = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname)); + PR_snprintf((char *)configname, 256, "%s.%d.SSLOn", prefix, instanceIndex); + m_isSSL = RA::GetConfigStore()->GetConfigAsBool(configname, true); + PR_snprintf((char *)configname, 256, "%s.%d.retries", prefix, instanceIndex); + m_retries = RA::GetConfigStore()->GetConfigAsInt(configname, 1); + PR_snprintf((char *)configname, 256, "%s.%d.retryConnect", prefix, instanceIndex); + m_connectRetries = RA::GetConfigStore()->GetConfigAsInt(configname, 3); + m_connInfo = new ConnectionInfo(); + m_connInfo->BuildFailoverList(m_hostport); + PR_snprintf((char *)configname, 256, "%s.%d.baseDN", prefix, instanceIndex); + m_baseDN = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname)); + PR_snprintf((char *)configname, 256, "%s.%d.attributes", prefix, instanceIndex); + m_attributes = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname)); + /* support of SSL */ + PR_snprintf((char *)configname, 256, "%s.%d.ssl", prefix, instanceIndex); + m_ssl = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname)); + PR_snprintf((char *)configname, 256, "%s.%d.bindDN", prefix, instanceIndex); + m_bindDN = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname)); + PR_snprintf((char *)configname, 256, "%s.%d.bindPWD", prefix, instanceIndex); + char *m_bindPwdPath = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname)); + m_bindPwd = get_pwd_from_conf(m_bindPwdPath, "tokendbBindPass"); +} + +/** + * @return (0:login correct) (-1:LDAP error) (-2:User not found) (-3:Password error) + */ + +#define TPS_AUTH_OK 0 +#define TPS_AUTH_ERROR_LDAP -1 +#define TPS_AUTH_ERROR_USERNOTFOUND -2 +#define TPS_AUTH_ERROR_PASSWORDINCORRECT -3 + +int LDAP_Authentication::Authenticate(AuthParams *params) +{ + char buffer[500]; + char ldapuri[1024]; + char *host = NULL; + char *portStr = NULL; + int port = 0; + LDAP *ld = NULL; + int status = TPS_AUTH_ERROR_LDAP; + int version = LDAP_VERSION3; + LDAPMessage *result = NULL, *e = NULL; + char *dn = NULL; + char *uid = NULL; + char *password = NULL; + int retries = 0; + int rc =0; + + if (params == NULL) { + status = TPS_AUTH_ERROR_USERNOTFOUND; + goto loser; + } + + uid = params->GetUID(); + password = params->GetPassword(); + + GetHostPort(&host, &portStr); + port = atoi(portStr); + + if ((m_ssl != NULL) && (strcmp(m_ssl, "true")==0)) { + /* handling of SSL */ + snprintf(ldapuri, 1024, "ldaps://%s:%i", host, port); + } else { + snprintf(ldapuri, 1024, "ldap://%s:%i", host, port); + } + status = ldap_initialize(&ld, ldapuri); + + while ((ld == NULL) && (retries < m_connectRetries)) { + RA::IncrementAuthCurrentIndex(m_connInfo->GetHostPortListLen()); + GetHostPort(&host, &portStr); + port = atoi(portStr); + if ((m_ssl != NULL) && (strcmp(m_ssl, "true")==0)) { + /* handling of SSL */ + snprintf(ldapuri, 1024, "ldaps://%s:%i", host, port); + } else { + snprintf(ldapuri, 1024, "ldap://%s:%i", host, port); + } + status = ldap_initialize(&ld, ldapuri); + retries++; + } + + if (ld == NULL) { + status = TPS_AUTH_ERROR_LDAP; + goto loser; + } + + PR_snprintf((char *)buffer, 500, "(uid=%s)", uid); + + while (retries < m_connectRetries) { + RA::IncrementAuthCurrentIndex(m_connInfo->GetHostPortListLen()); + GetHostPort(&host, &portStr); + port = atoi(portStr); + RA::Debug("ldap auth:"," host=%s, portstr=%s, port=%d", host, portStr, port); + if ((m_ssl != NULL) && (strcmp(m_ssl, "true")==0)) { + /* handling of SSL */ + snprintf(ldapuri, 1024, "ldaps://%s:%i", host, port); + } else { + snprintf(ldapuri, 1024, "ldap://%s:%i", host, port); + } + status = ldap_initialize(&ld, ldapuri); + + if (ld == NULL) { + RA::Debug("LDAP_Authentication::Authenticate:", "ld null. Trying failover..."); + retries++; + continue; + } + + if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) { + status = TPS_AUTH_ERROR_LDAP; + goto loser; + } + + if (m_bindDN != NULL && strlen(m_bindDN) > 0) { + RA::Debug("LDAP_Authentication::Authenticate", "Simple bind required '%s'", m_bindDN); + struct berval credential; + credential.bv_val = m_bindPwd; + credential.bv_len= strlen(m_bindPwd); + rc = ldap_sasl_bind_s(ld, m_bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL); + } + + int ldap_status = LDAP_OTHER; + if ((ldap_status = ldap_search_ext_s(ld, m_baseDN, LDAP_SCOPE_SUBTREE, buffer, NULL, 0, NULL, NULL, NULL, 0, &result)) != LDAP_SUCCESS) { + if (ldap_status != LDAP_NO_SUCH_OBJECT) { + RA::Debug("LDAP_Authentication::Authenticate:", "LDAP_UNAVAILABLE. Trying failover..."); + retries++; + continue; // do failover + } + status = TPS_AUTH_ERROR_USERNOTFOUND; + } else { + for (e = ldap_first_entry(ld, result); e != NULL; e = ldap_next_entry(ld, e)) { + if ((dn = ldap_get_dn(ld, e)) != NULL) { + RA::Debug("LDAP_Authentication::Authenticate", "User bind required '%s' '(sensitive)'", dn ); + struct berval credential; + credential.bv_val = password; + credential.bv_len= strlen(password); + rc = ldap_sasl_bind_s(ld, dn, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL); + if (rc == LDAP_SUCCESS) { + /* retrieve attributes and, */ + /* put them into the auth parameters */ + if (m_attributes != NULL) { + RA::Debug("LDAP_Authentication::Authenticate", "Attributes %s", m_attributes); + char *m_dup_attributes = strdup(m_attributes); + char *token = NULL; + token = strtok(m_dup_attributes, ","); + while( token != NULL ) { + struct berval **v = NULL; + v = ldap_get_values_len(ld, e, token); + if ((v != NULL) && (v[0]!= NULL) && (v[0]->bv_val != NULL)) { + RA::Debug("LDAP_Authentication::Authenticate", "Exposed %s=%s", token, v[0]->bv_val); + params->Add(token, PL_strdup(v[0]->bv_val)); + RA::Debug("LDAP_Authentication::Authenticate", "Size %d", params->Size()); + } + token = strtok( NULL, "," ); + if( v != NULL ) { + ldap_value_free_len( v ); + v = NULL; + } + + } + free(m_dup_attributes); + } + status = TPS_AUTH_OK; // SUCCESS - PASSWORD VERIFIED + } else { + status = TPS_AUTH_ERROR_PASSWORDINCORRECT; + goto loser; + } + } else { + status = TPS_AUTH_ERROR_USERNOTFOUND; + goto loser; + } + } + RA::Debug("LDAP_Authentication::Authenticate:", " authentication completed for %s",uid); + break; + } + } //while + + if (dn == NULL) { + status = TPS_AUTH_ERROR_USERNOTFOUND; + goto loser; + } + +loser: + + if (result != NULL) { + ldap_msgfree(result); + } + + if (dn != NULL) { + ldap_memfree(dn); + } + + if (ld != NULL) { + ldap_unbind_ext_s(ld, NULL, NULL); + ld = NULL; + } + return status; +} + +void LDAP_Authentication::GetHostPort(char **p, char **q) { + int num=0; + int auth_curr = RA::GetAuthCurrentIndex(); + char *hp = (m_connInfo->GetHostPortList())[auth_curr]; + char *host_port = PL_strdup(hp); + + char *lasts = NULL; + char *tok = PL_strtok_r((char *)host_port, ":", &lasts); + while (tok != NULL) { + if (num == 0) + *p = PL_strdup(tok); + else + *q = PL_strdup(tok); + tok = PL_strtok_r(NULL, ":", &lasts); + num++; + } + + PR_Free(host_port); +} + +bool LDAP_Authentication::IsSSL() { + return m_isSSL; +} + +char *LDAP_Authentication::GetHostPort() { + return m_hostport; +} + +Authentication *GetAuthentication() { + LDAP_Authentication *auth = new LDAP_Authentication(); + return (Authentication *)auth; +} + +const char *LDAP_Authentication::GetTitle(char *locale) +{ + char configname[256]; + const char *prefix="auth.instance"; + PR_snprintf((char *)configname, 256, "%s.%d.ui.title.%s", + prefix, m_index, locale); +RA::Debug("LDAP_Authentication::GetTitle", "%s", configname); + return RA::GetConfigStore()->GetConfigAsString(configname); +} + +const char *LDAP_Authentication::GetDescription(char *locale) +{ + char configname[256]; + const char *prefix="auth.instance"; + PR_snprintf((char *)configname, 256, "%s.%d.ui.description.%s", + prefix, m_index, locale); +RA::Debug("LDAP_Authentication::GetDescription", "%s", configname); +RA::Debug("LDAP_Authentication::GetDescription", "%s", RA::GetConfigStore()->GetConfigAsString(configname)); + return RA::GetConfigStore()->GetConfigAsString(configname); +} + +int LDAP_Authentication::GetNumOfParamNames() +{ + return 2; +} + +char *LDAP_Authentication::GetParamID(int index) +{ + if (index == 0) + return ( char * ) "UID"; + else if (index == 1) + return ( char * ) "PASSWORD"; + else + return NULL; +} + +const char *LDAP_Authentication::GetParamName(int index, char *locale) +{ + char configname[256]; + const char *prefix="auth.instance"; + PR_snprintf((char *)configname, 256, "%s.%d.ui.id.%s.name.%s", + prefix, m_index, GetParamID(index), locale); + +RA::Debug("LDAP_Authentication::GetParamName", "%s", configname); + + return RA::GetConfigStore()->GetConfigAsString(configname); +} + +char *LDAP_Authentication::GetParamType(int index) +{ + if (index == 0) + return ( char * ) "string"; + else if (index == 1) + return ( char * ) "password"; + else + return NULL; +} + +const char *LDAP_Authentication::GetParamDescription(int index, char *locale) +{ + char configname[256]; + const char *prefix="auth.instance"; + PR_snprintf((char *)configname, 256, "%s.%d.ui.id.%s.description.%s", + prefix, m_index, GetParamID(index), locale); + return RA::GetConfigStore()->GetConfigAsString(configname); +} + +char *LDAP_Authentication::GetParamOption(int index) +{ + return ( char * ) ""; +} + -- cgit