Add saslauth. This modules has been waiting in crox' branch for like ever

git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@880 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
psychon
2007-11-25 17:35:36 +00:00
parent 4e5bec326e
commit 3f27be8bde
3 changed files with 132 additions and 0 deletions
+14
View File
@@ -84,6 +84,9 @@ AC_ARG_ENABLE( [openssl],
AC_ARG_ENABLE( [perl],
AC_HELP_STRING([--disable-perl], [disable perl]),
[if test "$enableval" = "no" ; then NOPERL=1; fi],)
AC_ARG_ENABLE( [sasl],
AC_HELP_STRING([--enable-sasl], [enable sasl]),
[if test "$enableval" = "yes" ; then SASL=1; fi],)
appendCXX -Wall -W -Wno-unused
@@ -169,6 +172,11 @@ if test "$MODULES" = "yes"; then
AC_ERROR([Could not find perl binary. Try --disable-perl])
fi
fi
if test -n "$SASL"; then
AC_CHECK_LIB( sasl2, sasl_server_init,,
AC_ERROR([Could not find libsasl2.]))
fi
fi
fi
@@ -187,6 +195,7 @@ AC_SUBST([MODTARGET])
AC_SUBST([VERSION])
AC_SUBST([NOSSL])
AC_SUBST([PERL])
AC_SUBST([SASL])
AC_SUBST([MODDIR])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([znc-config])
@@ -211,4 +220,9 @@ if test x"$PERL" = "x" ; then
else
echo "perl: yes"
fi
if test x"$SASL" = "x" ; then
echo "sasl: no"
else
echo "sasl: yes"
fi
+17
View File
@@ -26,6 +26,10 @@ PERLHOOK :=
FILES := $(shell echo $(FILES) | sed -e "s/modperl//")
endif
ifeq "@SASL@" ""
FILES := $(shell echo $(FILES) | sed -e "s/saslauth//")
endif
SRCS := $(wildcard ../*.cpp) $(addsuffix .cpp, $(FILES))
OBJS := $(addsuffix .o, $(FILES))
TARGETS := $(addsuffix .so, $(FILES))
@@ -84,4 +88,17 @@ modperl_install:
@echo -n ""
endif
ifeq "@SASL@" "1"
saslauth.so: saslauth.o
$(CXX) $(LDFLAGS) -shared -o $@ $< -lsasl2
saslauth.o: saslauth.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) -c -o $@ $<
else
saslauth.so:
@echo -n ""
saslauth.o:
@echo -n ""
endif
-include .depend
+101
View File
@@ -0,0 +1,101 @@
/**
* @class CSASLAuthMod
* @author Heiko Hund <heiko@ist.eigentlich.net>
* @brief SASL authentication module for znc.
*
* Licensed under the GPLv2.
*/
#include <sasl/sasl.h>
#include "Modules.h"
#include "znc.h"
class CSASLAuthMod : public CGlobalModule {
public:
GLOBALMODCONSTRUCTOR(CSASLAuthMod) {
m_Cache.SetTTL(60000/*ms*/);
}
virtual ~CSASLAuthMod() {}
virtual bool OnBoot() {
return true;
}
virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
int i(0);
CString arg(sArgs.Token(i));
while (!arg.empty()) {
if (arg.StrCmp("saslauthd") || arg.StrCmp("auxprop")) {
method += arg + " ";
}
else {
CUtils::PrintError("Ignoring invalid SASL pwcheck method: " + arg);
}
arg = sArgs.Token(++i);
}
method.TrimRight();
if (sasl_server_init(NULL, NULL) != SASL_OK){
CUtils::PrintError("SASL Could Not Be Initialized - Halting Startup");
return false;
}
return true;
}
virtual EModRet OnLoginAttempt(CSmartPtr<CAuthBase> Auth) {
CString const user(Auth->GetUsername());
CString const pass(Auth->GetPassword());
CUser* pUser(CZNC::Get().FindUser(user));
sasl_conn_t *sasl_conn(0);
if (!pUser) { // @todo Will want to do some sort of && !m_bAllowCreate in the future
Auth->RefuseLogin("Invalid User - Halting SASL Authentication");
return HALT;
}
CString const key(CString(user + ":" + pass).MD5());
if (m_Cache.HasItem(key)) {
Auth->AcceptLogin(*pUser);
DEBUG_ONLY(cerr << "+++ Found in cache" << endl);
}
else if (sasl_server_new("znc", NULL, NULL, NULL, NULL, cbs, 0, &sasl_conn) == SASL_OK &&
sasl_checkpass(sasl_conn, user.c_str(), user.size(), pass.c_str(), pass.size()) == SASL_OK) {
Auth->AcceptLogin(*pUser);
m_Cache.AddItem(key);
DEBUG_ONLY(cerr << "+++ Successful SASL password check" << endl);
}
else {
Auth->RefuseLogin("SASL Authentication failed");
DEBUG_ONLY(cerr << "--- FAILED SASL password check" << endl);
}
sasl_dispose(&sasl_conn);
return HALT;
}
private:
TCacheMap<CString> m_Cache;
static sasl_callback_t cbs[];
static CString method;
static int getopt(void *context, const char *plugin_name, const char *option, const char **result, unsigned *len) {
if (!method.empty() && strcmp(option, "pwcheck_method") == 0) {
*result = method.c_str();
return SASL_OK;
}
return SASL_CONTINUE;
}
};
sasl_callback_t CSASLAuthMod::cbs[] = {
{ SASL_CB_GETOPT, reinterpret_cast<int(*)()>(CSASLAuthMod::getopt), NULL },
{ SASL_CB_LIST_END, NULL, NULL }
};
CString CSASLAuthMod::method;
GLOBALMODULEDEFS(CSASLAuthMod, "Allow users to authenticate via SASL password verification method")