Files
resiprocate/repro/ReproAuthenticatorFactory.cxx
2020-08-05 21:27:15 +01:00

254 lines
8.3 KiB
C++

#include <iostream>
#include <fstream>
#include <memory>
#include <stdexcept>
#include <utility>
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#include "rutil/Logger.hxx"
#include "AclStore.hxx"
#include "ReproAuthenticatorFactory.hxx"
#include "ReproRADIUSServerAuthManager.hxx"
#include "ReproServerAuthManager.hxx"
#include "ReproTlsPeerAuthManager.hxx"
#include "UserAuthGrabber.hxx"
#include "resip/stack/Worker.hxx"
#include "monkeys/CertificateAuthenticator.hxx"
#include "monkeys/DigestAuthenticator.hxx"
#include "monkeys/RADIUSAuthenticator.hxx"
using namespace std;
using namespace resip;
using namespace repro;
#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
ReproAuthenticatorFactory::ReproAuthenticatorFactory(ProxyConfig& proxyConfig, SipStack& sipStack, DialogUsageManager* dum)
: mProxyConfig(proxyConfig),
mSipStack(sipStack),
mDum(dum),
mEnableCertAuth(mProxyConfig.getConfigBool("EnableCertificateAuthenticator", false)),
mEnableDigestAuth(!mProxyConfig.getConfigBool("DisableAuth", false)),
mEnableRADIUS(mProxyConfig.getConfigBool("EnableRADIUS", false)),
mRADIUSConfiguration(mProxyConfig.getConfigData("RADIUSConfiguration", "")),
mStaticRealm(mProxyConfig.getConfigData("StaticRealm", "")),
mDigestChallengeThirdParties(!mEnableCertAuth),
mCertificateAuthManager((DumFeature*)0),
mServerAuthManager((ServerAuthManager*)0)
{
}
ReproAuthenticatorFactory::~ReproAuthenticatorFactory()
{
}
void
ReproAuthenticatorFactory::init()
{
if(!mAuthRequestDispatcher.get())
{
int numAuthGrabberWorkerThreads = mProxyConfig.getConfigInt("NumAuthGrabberWorkerThreads", 2);
if(numAuthGrabberWorkerThreads < 1)
{
numAuthGrabberWorkerThreads = 1; // must have at least one thread
}
std::unique_ptr<Worker> grabber(new UserAuthGrabber(*mProxyConfig.getDataStore()));
mAuthRequestDispatcher.reset(new Dispatcher(std::move(grabber), &mSipStack, numAuthGrabberWorkerThreads));
}
// TODO: should be implemented using AbstractDb
loadCommonNameMappings();
}
void
ReproAuthenticatorFactory::loadCommonNameMappings()
{
// Already loaded?
if(!mCommonNameMappings.empty())
return;
Data mappingsFileName = mProxyConfig.getConfigData("CommonNameMappings", "");
if(mappingsFileName.empty())
return;
InfoLog(<< "trying to load common name mappings from file: " << mappingsFileName);
ifstream mappingsFile(mappingsFileName.c_str());
if(!mappingsFile)
{
ErrLog(<< "failed to open mappings file: " << mappingsFileName << ", aborting");
throw std::runtime_error("Error opening/reading mappings file");
}
string sline;
while(getline(mappingsFile, sline))
{
Data line(sline);
Data cn;
PermittedFromAddresses permitted;
ParseBuffer pb(line);
pb.skipWhitespace();
const char * anchor = pb.position();
if(pb.eof() || *anchor == '#') continue; // if line is a comment or blank then skip it
// Look for end of name
pb.skipToOneOf("\t");
pb.data(cn, anchor);
if(mCommonNameMappings.find(cn) != mCommonNameMappings.end())
{
ErrLog(<< "CN '" << cn << "' repeated in mappings file");
throw std::runtime_error("CN repeated in mappings file");
}
pb.skipChar('\t');
while(!pb.eof())
{
pb.skipWhitespace();
if(pb.eof())
continue;
Data value;
anchor = pb.position();
pb.skipToOneOf(",\r\n ");
pb.data(value, anchor);
if(!value.empty())
{
StackLog(<< "Loading CN '" << cn << "', found mapping '" << value << "'");
permitted.insert(value);
}
if(!pb.eof())
pb.skipChar();
}
DebugLog(<< "Loaded mapping for CN '" << cn << "', " << permitted.size() << " mapping(s)");
mCommonNameMappings[cn] = permitted;
}
}
std::shared_ptr<DumFeature>
ReproAuthenticatorFactory::getCertificateAuthManager()
{
init();
if(!mCertificateAuthManager.get())
{
Store *db = mProxyConfig.getDataStore();
resip_assert(db);
AclStore& aclStore = db->mAclStore;
mCertificateAuthManager.reset(new ReproTlsPeerAuthManager(*mDum, mDum->dumIncomingTarget(), getDispatcher(), aclStore, true, mCommonNameMappings));
}
return mCertificateAuthManager;
}
std::unique_ptr<Processor>
ReproAuthenticatorFactory::getCertificateAuthenticator()
{
init();
Store *db = mProxyConfig.getDataStore();
resip_assert(db);
AclStore& aclStore = db->mAclStore;
return std::unique_ptr<Processor>(new CertificateAuthenticator(mProxyConfig, getDispatcher(), &mSipStack, aclStore, true, mCommonNameMappings));
}
std::shared_ptr<ServerAuthManager>
ReproAuthenticatorFactory::getServerAuthManager()
{
init();
if(!mServerAuthManager.get())
{
if(mEnableRADIUS)
{
#ifdef USE_RADIUS_CLIENT
mServerAuthManager.reset(new ReproRADIUSServerAuthManager(*mDum,
mProxyConfig.getDataStore()->mAclStore,
!mProxyConfig.getConfigBool("DisableAuthInt", false) /*useAuthInt*/,
mProxyConfig.getConfigBool("RejectBadNonces", false),
mRADIUSConfiguration,
mDigestChallengeThirdParties,
mStaticRealm));
#else
ErrLog(<<"can't create ReproRADIUSServerAuthManager, not compiled with RADIUS support");
#endif
}
else
{
mServerAuthManager.reset(new ReproServerAuthManager(*mDum,
getDispatcher(),
mProxyConfig.getDataStore()->mAclStore,
!mProxyConfig.getConfigBool("DisableAuthInt", false) /*useAuthInt*/,
mProxyConfig.getConfigBool("RejectBadNonces", false),
mDigestChallengeThirdParties,
mStaticRealm));
}
}
return mServerAuthManager;
}
std::unique_ptr<Processor>
ReproAuthenticatorFactory::getDigestAuthenticator()
{
init();
if(mEnableRADIUS)
{
#ifdef USE_RADIUS_CLIENT
return std::unique_ptr<Processor>(new RADIUSAuthenticator(mProxyConfig, mRADIUSConfiguration, mStaticRealm));
#else
ErrLog(<<"can't create RADIUSAuthenticator, not compiled with RADIUS support");
return nullptr;
#endif
}
else
{
return std::unique_ptr<Processor>(new DigestAuthenticator(mProxyConfig, getDispatcher(), mStaticRealm));
}
}
Dispatcher*
ReproAuthenticatorFactory::getDispatcher()
{
init();
return mAuthRequestDispatcher.get();
}
/* ====================================================================
* BSD License
*
* Copyright (c) 2013 Daniel Pocock http://danielpocock.com All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the author(s) nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* ====================================================================
*
*/