Showing with 163 additions and 31 deletions.
  1. +6 −4 CMakeLists.txt
  2. +3 −3 cmake/FindGettext.cmake
  3. +3 −3 include/CMakeLists.txt
  4. +34 −0 modules/CMakeLists.txt
  5. +86 −11 modules/extra/m_ldap.cpp
  6. +1 −1 modules/extra/m_regex_pcre2.cpp
  7. +1 −1 modules/extra/m_ssl_openssl.cpp
  8. +8 −8 src/mail.cpp
  9. +21 −0 src/win32/conanfile.txt
10 changes: 6 additions & 4 deletions CMakeLists.txt
Expand Up @@ -229,6 +229,12 @@ if(EXTRA_LIBS)
link_directories(${EXTRA_LIBS})
endif(EXTRA_LIBS)

# setup conan
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/conanbuildinfo.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/conanbuildinfo.cmake")
conan_basic_setup()
endif()

# Find gettext
find_package(Gettext)

Expand Down Expand Up @@ -502,10 +508,6 @@ if(WIN32)
install(FILES ${Anope_SOURCE_DIR}/src/win32/anope.bat
DESTINATION ${BIN_DIR}
)

# Package any DLLs in src/win/
file(GLOB EXTRA_DLLS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${Anope_SOURCE_DIR}/src/win32/*.dll")
install(FILES ${EXTRA_DLLS} DESTINATION ${BIN_DIR})
endif(WIN32)

install(CODE "file(REMOVE_RECURSE \"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/modules\")")
Expand Down
6 changes: 3 additions & 3 deletions cmake/FindGettext.cmake
Expand Up @@ -10,9 +10,9 @@ if(NOT WIN32)
endif(GETTEXT_LIBRARY)
endif(GETTEXT_INCLUDE AND GETTEXT_MSGFMT)
else(NOT WIN32)
find_path(GETTEXT_INCLUDE libintl.h ${DEFAULT_INCLUDE_DIRS} ${WSDK_PATH}/include $ENV{VCINSTALLDIR}/include gettext/include ${EXTRA_INCLUDE})
find_library(GETTEXT_LIBRARY libintl PATHS ${DEFAULT_LIBRARY_DIRS} ${WSDK_PATH}/lib $ENV{VCINSTALLDIR}/lib gettext/lib ${EXTRA_LIBS})
find_program(GETTEXT_MSGFMT msgfmt PATHS ${DEFAULT_INCLUDE_DIRS} ${WSDK_PATH}/bin $ENV{VCINSTALLDIR}/bin gettext/bin ${EXTRA_INCLUDE})
find_path(GETTEXT_INCLUDE libintl.h)
find_library(GETTEXT_LIBRARY gnuintl)
find_program(GETTEXT_MSGFMT msgfmt)
if(GETTEXT_INCLUDE AND GETTEXT_LIBRARY AND GETTEXT_MSGFMT)
set(GETTEXT_FOUND TRUE)
set(GETTEXT_LIBRARIES ${GETTEXT_LIBRARY})
Expand Down
6 changes: 3 additions & 3 deletions include/CMakeLists.txt
Expand Up @@ -6,8 +6,8 @@ set_target_properties(version-bin PROPERTIES LINKER_LANGUAGE CXX LINK_FLAGS "${L
get_target_property(version_BINARY version-bin LOCATION)
# Modify version.h from the above executable, with dependencies to version.cpp
# and all of the source files in the main build
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version_build
COMMAND ${version_BINARY} ${Anope_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/version.h ${CMAKE_CURRENT_BINARY_DIR}/build.h
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version.h ${CMAKE_CURRENT_BINARY_DIR}/build.h
COMMAND version-bin ${Anope_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/version.h ${CMAKE_CURRENT_BINARY_DIR}/build.h
DEPENDS version-bin ${SRC_SRCS}
)
# Add version-bin to list of files for CPack to ignore
Expand Down Expand Up @@ -61,4 +61,4 @@ if(USE_PCH AND CMAKE_COMPILER_IS_GNUCXX)
endif(USE_PCH AND CMAKE_COMPILER_IS_GNUCXX)

# Add a custom target to the above file
add_custom_target(headers DEPENDS version-bin ${CMAKE_CURRENT_BINARY_DIR}/version_build ${PCH_SOURCES_GCH})
add_custom_target(headers DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/version.h ${CMAKE_CURRENT_BINARY_DIR}/build.h ${PCH_SOURCES_GCH})
34 changes: 34 additions & 0 deletions modules/CMakeLists.txt
Expand Up @@ -3,6 +3,40 @@ if(WIN32)
add_definitions(-DMODULE_COMPILE)
endif(WIN32)

# enable extra modules if conan is used
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../conanbuildinfo.cmake")
function(enable_extra NAME PACKAGE)
if(DEFINED "CONAN_${PACKAGE}_ROOT")
message("Enabling the ${NAME} module")
# copy the modules out of extra so it gets picked up by build_modules
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/extra/${NAME}.cpp" DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}")
else()
message("Unable to enable the ${NAME} module (missing library)")
endif()
endfunction()

function(copy_extra NAME)
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/extra/${NAME}.cpp" DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}")
endfunction()

enable_extra("m_mysql" "LIBMYSQLCLIENT")
enable_extra("m_regex_pcre2" "PCRE2")
enable_extra("m_sqlite" "SQLITE3")
enable_extra("m_ssl_openssl" "OPENSSL")
# this uses Wldap so should always be available
copy_extra("m_ldap")
# these don't actually have extra dependencies, but require a module which does
copy_extra("m_sql_authentication")
copy_extra("m_sql_log")
copy_extra("m_sql_oper")
copy_extra("m_ldap_authentication")
copy_extra("m_ldap_oper")

# Package extra dlls
file(GLOB EXTRA_DLLS "${Anope_SOURCE_DIR}/extradll/bin/*.dll" "${Anope_SOURCE_DIR}/extradll/lib/*.dll")
install(FILES ${EXTRA_DLLS} DESTINATION ${BIN_DIR})
endif()

macro(build_modules SRC)
if(NOT ${SRC} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} AND EXISTS "${SRC}/CMakeLists.txt")
add_subdirectory("${SRC}")
Expand Down
97 changes: 86 additions & 11 deletions modules/extra/m_ldap.cpp
Expand Up @@ -10,11 +10,29 @@
*/

/* RequiredLibraries: ldap_r|ldap,lber */
/* RequiredWindowsLibraries: libldap_r|libldap,liblber */

#include "module.h"
#include "modules/ldap.h"
#include <ldap.h>

#ifdef _WIN32
# include <Winldap.h>
# include <WinBer.h>
# include <wininet.h>
# define LDAP_OPT_SUCCESS LDAP_SUCCESS
# define LDAP_OPT_NETWORK_TIMEOUT LDAP_OPT_SEND_TIMEOUT
# define LDAP_STR(X) const_cast<PSTR>((X).c_str())
# define LDAP_SASL_SIMPLE static_cast<PSTR>(0)
# define LDAP_TIME(X) reinterpret_cast<PLDAP_TIMEVAL>(&(X))
# define ldap_first_message ldap_first_entry
# define ldap_next_message ldap_next_entry
# define ldap_unbind_ext(LDAP, UNUSED1, UNUSED2) ldap_unbind(LDAP)
# pragma comment(lib, "Wldap32.lib")
# pragma comment(lib, "Wininet.lib")
#else
# include <ldap.h>
# define LDAP_STR(X) ((X).c_str())
# define LDAP_TIME(X) (&(X))
#endif

#if defined LDAP_API_FEATURE_X_OPENLDAP_REENTRANT && !LDAP_API_FEATURE_X_OPENLDAP_REENTRANT
# error Anope requires OpenLDAP to be built as reentrant.
Expand Down Expand Up @@ -73,13 +91,13 @@ class LDAPBind : public LDAPRequest
int run() anope_override;
};

class LDAPSearch : public LDAPRequest
class LDAPSearchRequest : public LDAPRequest
{
Anope::string base;
Anope::string filter;

public:
LDAPSearch(LDAPService *s, LDAPInterface *i, const Anope::string &b, const Anope::string &f)
LDAPSearchRequest(LDAPService *s, LDAPInterface *i, const Anope::string &b, const Anope::string &f)
: LDAPRequest(s, i)
, base(b)
, filter(f)
Expand Down Expand Up @@ -190,6 +208,63 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
}

private:
#ifdef _WIN32
// Windows LDAP does not implement this so we need to do it.
int ldap_initialize(LDAP** ldap, const char* url)
{
URL_COMPONENTS urlComponents;
memset(&urlComponents, 0, sizeof(urlComponents));
urlComponents.dwStructSize = sizeof(urlComponents);

urlComponents.lpszScheme = new char[8];
urlComponents.dwSchemeLength = 8;

urlComponents.lpszHostName = new char[1024];
urlComponents.dwHostNameLength = 1024;

if (!InternetCrackUrlA(url, 0, 0, &urlComponents))
{
delete[] urlComponents.lpszScheme;
delete[] urlComponents.lpszHostName;
return LDAP_CONNECT_ERROR; // Malformed url.
}

unsigned long port = 389; // Default plaintext port.
bool secure = false; // LDAP defaults to plaintext.
if (urlComponents.dwSchemeLength > 0)
{
const Anope::string scheme(urlComponents.lpszScheme);
if (scheme.equals_ci("ldaps"))
{
port = 636; // Default encrypted port.
secure = true;
}
else if (!scheme.equals_ci("ldap"))
{
delete[] urlComponents.lpszScheme;
delete[] urlComponents.lpszHostName;
return LDAP_CONNECT_ERROR; // Invalid protocol.
}
}

if (urlComponents.nPort > 0)
{
port = urlComponents.nPort;
}

*ldap = ldap_sslinit(urlComponents.lpszHostName, port, secure);
delete[] urlComponents.lpszScheme;
delete[] urlComponents.lpszHostName;
if (!*ldap)
{
return LdapGetLastError(); // Something went wrong, find out what.
}

// We're connected to the LDAP server!
return LDAP_SUCCESS;
}
#endif

void Connect()
{
int i = ldap_initialize(&this->con, this->server.c_str());
Expand Down Expand Up @@ -291,7 +366,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
if (i == NULL)
throw LDAPException("No interface");

LDAPSearch *s = new LDAPSearch(this, i, base, filter);
LDAPSearchRequest *s = new LDAPSearchRequest(this, i, base, filter);
QueueRequest(s);
}

Expand Down Expand Up @@ -590,35 +665,35 @@ int LDAPBind::run()
cred.bv_val = strdup(pass.c_str());
cred.bv_len = pass.length();

int i = ldap_sasl_bind_s(service->GetConnection(), who.c_str(), LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
int i = ldap_sasl_bind_s(service->GetConnection(), LDAP_STR(who), LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);

free(cred.bv_val);

return i;
}

int LDAPSearch::run()
int LDAPSearchRequest::run()
{
return ldap_search_ext_s(service->GetConnection(), base.c_str(), LDAP_SCOPE_SUBTREE, filter.c_str(), NULL, 0, NULL, NULL, &tv, 0, &message);
return ldap_search_ext_s(service->GetConnection(), LDAP_STR(base), LDAP_SCOPE_SUBTREE, LDAP_STR(filter), NULL, 0, NULL, NULL, LDAP_TIME(tv), 0, &message);
}

int LDAPAdd::run()
{
LDAPMod **mods = LDAPService::BuildMods(attributes);
int i = ldap_add_ext_s(service->GetConnection(), dn.c_str(), mods, NULL, NULL);
int i = ldap_add_ext_s(service->GetConnection(), LDAP_STR(dn), mods, NULL, NULL);
LDAPService::FreeMods(mods);
return i;
}

int LDAPDel::run()
{
return ldap_delete_ext_s(service->GetConnection(), dn.c_str(), NULL, NULL);
return ldap_delete_ext_s(service->GetConnection(), LDAP_STR(dn), NULL, NULL);
}

int LDAPModify::run()
{
LDAPMod **mods = LDAPService::BuildMods(attributes);
int i = ldap_modify_ext_s(service->GetConnection(), base.c_str(), mods, NULL, NULL);
int i = ldap_modify_ext_s(service->GetConnection(), LDAP_STR(base), mods, NULL, NULL);
LDAPService::FreeMods(mods);
return i;
}
Expand Down
2 changes: 1 addition & 1 deletion modules/extra/m_regex_pcre2.cpp
Expand Up @@ -7,7 +7,7 @@
*/

/* RequiredLibraries: pcre2-8 */
/* RequiredWindowsLibraries: libpcre2-8 */
/* RequiredWindowsLibraries: pcre2-8 */

#include "module.h"

Expand Down
2 changes: 1 addition & 1 deletion modules/extra/m_ssl_openssl.cpp
Expand Up @@ -7,7 +7,7 @@
*/

/* RequiredLibraries: ssl,crypto */
/* RequiredWindowsLibraries: ssleay32,libeay32 */
/* RequiredWindowsLibraries: libssl,libcrypto */

#include "module.h"
#include "modules/ssl.h"
Expand Down
16 changes: 8 additions & 8 deletions src/mail.cpp
Expand Up @@ -35,17 +35,17 @@ void Mail::Message::Run()
return;
}

fprintf(pipe, "From: %s\n", send_from.c_str());
fprintf(pipe, "From: %s\r\n", send_from.c_str());
if (this->dont_quote_addresses)
fprintf(pipe, "To: %s <%s>\n", mail_to.c_str(), addr.c_str());
fprintf(pipe, "To: %s <%s>\r\n", mail_to.c_str(), addr.c_str());
else
fprintf(pipe, "To: \"%s\" <%s>\n", mail_to.c_str(), addr.c_str());
fprintf(pipe, "Subject: %s\n", subject.c_str());
fprintf(pipe, "Content-Type: text/plain; charset=UTF-8;\n");
fprintf(pipe, "Content-Transfer-Encoding: 8bit\n");
fprintf(pipe, "\n");
fprintf(pipe, "To: \"%s\" <%s>\r\n", mail_to.c_str(), addr.c_str());
fprintf(pipe, "Subject: %s\r\n", subject.c_str());
fprintf(pipe, "Content-Type: text/plain; charset=UTF-8;\r\n");
fprintf(pipe, "Content-Transfer-Encoding: 8bit\r\n");
fprintf(pipe, "\r\n");
fprintf(pipe, "%s", message.c_str());
fprintf(pipe, "\n.\n");
fprintf(pipe, "\r\n.\r\n");

pclose(pipe);

Expand Down
21 changes: 21 additions & 0 deletions src/win32/conanfile.txt
@@ -0,0 +1,21 @@
[requires]
libmysqlclient/8.0.31
openssl/1.1.1t
pcre2/10.42
sqlite3/3.41.1
gettext/0.21
libgettext/0.21

[options]
libmysqlclient/*:shared=True
openssl/*:shared=True
pcre2/*:shared=True
sqlite3/*:shared=True
libgettext/*:shared=True

[imports]
., *.dll -> extradll
., *.lib -> extralib

[generators]
cmake