Commit 2b53e5d4 authored by François Grisez's avatar François Grisez

Reworking of Authentication module and creation of ExetrnalAuthentication plugin

parent 5ac1a5ee
Pipeline #1286 passed with stages
in 37 minutes and 20 seconds
......@@ -52,6 +52,7 @@ option(ENABLE_SOCI "Build with SOCI support" YES)
option(ENABLE_STATIC "Build static library (default is shared library)." NO)
option(ENABLE_TRANSCODER "Build transcoder support" YES)
option(ENABLE_MDNS "Build multicast DNS support" NO)
option(ENABLE_EXTERNAL_AUTH_PLUGIN "Enable ExternalAuth plugin support" NO)
option(ENABLE_JWE_AUTH_PLUGIN "Enable JweAuth plugin support" NO)
cmake_dependent_option(ENABLE_SPECIFIC_FEATURES "Enable mediarelay specific features" OFF "ENABLE_TRANSCODER" OFF)
......
......@@ -94,6 +94,20 @@ JweAuth plugin offers the possibility to use JSON Web Encryption tokens on flexi
%endif
%if @ENABLE_EXTERNAL_AUTH_PLUGIN@
%package external-auth-plugin
Summary: Add the ability to delegate authentication process to an external HTTP server
Group: Security
Requires: %{name} = %{version}-%{release}
%description external-auth-plugin
Add the ability to delegate authentication process to an external HTTP server.
%endif
# This is for debian builds where debug_package has to be manually specified, whereas in centos it does not
%define custom_debug_package %{!?_enable_debug_packages:%debug_package}%{?_enable_debug_package:%{nil}}
%custom_debug_package
......@@ -232,6 +246,14 @@ fi
%{_libdir}/flexisip/plugins/libjweauth.so.*
%endif
%if @ENABLE_EXTERNAL_AUTH_PLUGIN@
%files external-auth-plugin
%defattr(-,root,root,-)
%{_libdir}/flexisip/plugins/libexternal-auth.so
%{_libdir}/flexisip/plugins/libexternal-auth.so.*
%endif
%changelog
* Tue Nov 27 2018 ronan.abhamon <ronan.abhamon@belledonne-communications.com>
......
......@@ -35,6 +35,10 @@ set(FLEXISIP_DEPENDENCIES)
set(FLEXISIP_SOURCES
agent.cc
auth/auth-module.cc
auth/flexisip-auth-module.cc
auth/flexisip-auth-module-base.cc
auth/nonce-store.cc
authdb-file.cc
authdb.cc
callcontext-mediarelay.cc
......@@ -100,6 +104,7 @@ set(FLEXISIP_SOURCES
transaction.cc
uac-register.cc
utils/httputils.cc
utils/string-formater.cc
utils/string-utils.cc
utils/threadpool.cc
)
......@@ -330,6 +335,10 @@ install(TARGETS flexisip_pusher
)
# Build plugins.
if(ENABLE_EXTERNAL_AUTH_PLUGIN)
add_subdirectory(plugin/external-auth-plugin)
endif()
if(ENABLE_JWE_AUTH_PLUGIN)
add_subdirectory(plugin/jwe-auth-plugin)
endif()
......
/*
* Flexisip, a flexible SIP proxy server with media capabilities.
* Copyright (C) 2018 Belledonne Communications SARL, All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sstream>
#include <stdexcept>
#include <sofia-sip/auth_plugin.h>
#include <sofia-sip/su_tagarg.h>
#include "log/logmanager.hh"
#include "auth-module.hh"
using namespace std;
struct auth_plugin_t {
AuthModule *backPtr;
};
struct auth_mod_plugin_t {
auth_mod_t module[1];
auth_plugin_t plugin[1];
};
AuthModule::AuthModule(su_root_t *root, tag_type_t tag, tag_value_t value, ...) : mRoot(root) {
ta_list ta;
registerScheme();
ta_start(ta, tag, value);
mAm = auth_mod_create(root, AUTHTAG_METHOD(sMethodName), ta_tags(ta));
ta_end(ta);
if (mAm == nullptr) {
ostringstream os;
os << "couldn't create '" << sMethodName << "' authentication module";
throw logic_error(os.str());
}
(AUTH_PLUGIN(mAm))->backPtr = this;
}
void AuthModule::checkCb(auth_mod_t *am, auth_status_t *as, msg_auth_t *auth, auth_challenger_t const *ch) noexcept {
AuthStatus &authStatus = *reinterpret_cast<AuthStatus *>(as->as_plugin);
(AUTH_PLUGIN(am))->backPtr->onCheck(authStatus, auth, ch);
}
void AuthModule::challengeCb(auth_mod_t *am, auth_status_t *as, auth_challenger_t const *ach) noexcept {
AuthStatus &authStatus = *reinterpret_cast<AuthStatus *>(as->as_plugin);
(AUTH_PLUGIN(am))->backPtr->onChallenge(authStatus, ach);
}
void AuthModule::cancelCb(auth_mod_t *am, auth_status_t *as) noexcept {
AuthStatus &authStatus = *reinterpret_cast<AuthStatus *>(as->as_plugin);
(AUTH_PLUGIN(am))->backPtr->onCancel(authStatus);
}
void AuthModule::registerScheme() {
if (!sSchemeRegistered) {
if (auth_mod_register_plugin(&sAuthScheme) != 0) {
ostringstream os;
os << "couldn't register '" << sMethodName << "' authentication plugin";
throw logic_error(os.str());
}
}
}
const char *AuthModule::sMethodName = "flexisip";
auth_scheme_t AuthModule::sAuthScheme = {
sMethodName,
sizeof(auth_mod_plugin_t),
auth_init_default,
checkCb,
challengeCb,
cancelCb,
auth_destroy_default
};
bool AuthModule::sSchemeRegistered = false;
/*
* Flexisip, a flexible SIP proxy server with media capabilities.
* Copyright (C) 2018 Belledonne Communications SARL, All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <memory>
#include <sofia-sip/auth_module.h>
#include "auth-status.hh"
/**
* @brief Interface for authentication modules.
* @note This class is a plain C++ wrapper of SofiaSip's auth_mod_t
* object. Please look at http://sofia-sip.sourceforge.net/refdocs/iptsec/auth__module_8h.html
* for a complete documentation.
*/
class AuthModule {
public:
AuthModule(su_root_t *root, tag_type_t, tag_value_t, ...);
virtual ~AuthModule() {auth_mod_destroy(mAm);}
/**
* Return a pointer on the underlying SofiaSip's authentication module.
* This method is useful if you mean to call a SofiaSip function that needs
* an auth_mod_t object as parameter.
*/
auth_mod_t *getPtr() const {return mAm;}
/**
* Event loop which the authentication module is working on.
* This has been define on module construction.
*/
su_root_t *getRoot() const {return mRoot;}
/**
* These methods are C++ version of public method of auth_mod_t API. To find the associated
* SofiaSip function, just prefix the name of the method by "auth_mod_" e.g. verify() -> auth_mod_verify().
*/
void verify(AuthStatus &as, msg_auth_t *credentials, auth_challenger_t const *ach) {auth_mod_verify(mAm, as.getPtr(), credentials, ach);}
void challenge(AuthStatus &as, auth_challenger_t const *ach) {auth_mod_challenge(mAm, as.getPtr(), ach);}
void authorize(AuthStatus &as, auth_challenger_t const *ach) {auth_mod_challenge(mAm, as.getPtr(), ach);}
void cancel(AuthStatus &as) {auth_mod_cancel(mAm, as.getPtr());}
protected:
virtual void onCheck(AuthStatus &as, msg_auth_t *credentials, auth_challenger_t const *ach) = 0;
virtual void onChallenge(AuthStatus &as, auth_challenger_t const *ach) = 0;
virtual void onCancel(AuthStatus &as) = 0;
auth_mod_t *mAm = nullptr;
private:
static void checkCb(auth_mod_t *am, auth_status_t *as, msg_auth_t *auth, auth_challenger_t const *ch) noexcept;
static void challengeCb(auth_mod_t *am, auth_status_t *as, auth_challenger_t const *ach) noexcept;
static void cancelCb(auth_mod_t *am, auth_status_t *as) noexcept;
static void registerScheme();
su_root_t *mRoot = nullptr;
static const char *sMethodName;
static auth_scheme_t sAuthScheme;
static bool sSchemeRegistered;
};
/*
* Flexisip, a flexible SIP proxy server with media capabilities.
* Copyright (C) 2018 Belledonne Communications SARL, All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <functional>
#include <sofia-sip/auth_module.h>
/**
* @brief Plain C++ wrapper for SofiaSip's auth_status_t structure.
* @warning Like auth_status_t, this classe doesn't take ownership
* on strings that have been set by setters. That means you must
* guarantees the life of such strings while the authentication is processing.
* If you cannot, you may copy the string by using the AuthStatus' internal
* home_t object before giving it to the setter method. This one can be
* got thanks to home() method.
* @see See http://sofia-sip.sourceforge.net/refdocs/iptsec/structauth__status__t.html
* for more documentation.
*/
class AuthStatus {
public:
using ResponseCb = std::function<void(AuthStatus &as)>;
AuthStatus() {
su_home_init(&mHome);
mPriv = auth_status_new(&mHome);
mPriv->as_plugin = reinterpret_cast<auth_splugin_t *>(this);
mPriv->as_callback = responseCb;
}
virtual ~AuthStatus() {su_home_deinit(&mHome);}
bool allow() const {return mPriv->as_allow;}
void allow(bool val) {mPriv->as_allow = val;}
bool anonymous() const {return mPriv->as_anonymous;}
void anonymous(bool val) {mPriv->as_anonymous = val;}
const void *body() const {return mPriv->as_body;}
void body(const void *val) {mPriv->as_body = val;}
isize_t bodyLen() const {return mPriv->as_bodylen;}
void bodyLen(isize_t val) {mPriv->as_bodylen = val;}
bool blacklist() const {return mPriv->as_blacklist;}
void blacklist(bool val) {mPriv->as_blacklist = val;}
const ResponseCb &callback() const {return mResponseCb;}
void callback(const ResponseCb &cb) {mResponseCb = cb;}
const char *display() const {return mPriv->as_display;}
void display(const char *val) {mPriv->as_display = val;}
/**
* Internal home_t, which will be destroyed on destruction
* of the AuthStatus.
*/
su_home_t *home() {return mPriv->as_home;}
msg_header_t *info() const {return mPriv->as_info;}
void info(msg_header_t *val) {mPriv->as_info = val;}
auth_magic_t *magic() const {return mPriv->as_magic;}
void magic(auth_magic_t *val) {mPriv->as_magic = val;}
msg_header_t *match() const {return mPriv->as_match;}
void match(msg_header_t *val) {mPriv->as_match = val;}
const char *method() const {return mPriv->as_method;}
void method(const char *val) {mPriv->as_method = val;}
msg_time_t nonceIssued() const {return mPriv->as_nonce_issued;}
void nonceIssued(msg_time_t val) {mPriv->as_nonce_issued = val;}
const char *phrase() const {return mPriv->as_phrase;}
void phrase(const char *val) {mPriv->as_phrase = val;}
const char *realm() const {return mPriv->as_realm;}
void realm(const char *val) {mPriv->as_realm = val;}
msg_header_t *response() const {return mPriv->as_response;}
void response(msg_header_t *val) {mPriv->as_response = val;}
su_addrinfo_t *source() const {return mPriv->as_source;}
void source(su_addrinfo_t *val) {mPriv->as_source = val;}
bool stale() const {return mPriv->as_stale;}
void stale(bool val) {mPriv->as_stale = val;}
int status() const {return mPriv->as_status;}
void status(int val) {mPriv->as_status = val;}
const char *user() const {return mPriv->as_user;}
void user(const char *val) {mPriv->as_user = val;}
const url_t *userUri() const {return mPriv->as_user_uri;}
void userUri(const url_t *val) {mPriv->as_user_uri = val;}
/**
* Return the underlying SofiaSip's auth_status_t object.
*/
auth_status_t *getPtr() {return mPriv;}
private:
static void responseCb(auth_magic_t *magic, auth_status_t *as) {
AuthStatus &authStatus = *reinterpret_cast<AuthStatus *>(as->as_plugin);
if (authStatus.mResponseCb) authStatus.mResponseCb(authStatus);
}
su_home_t mHome;
auth_status_t *mPriv = nullptr;
ResponseCb mResponseCb;
};
/*
* Flexisip, a flexible SIP proxy server with media capabilities.
* Copyright (C) 2018 Belledonne Communications SARL, All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sofia-sip/auth_plugin.h>
#include <sofia-sip/msg_header.h>
#include "log/logmanager.hh"
#include "module.hh"
#include "flexisip-auth-module-base.hh"
using namespace std;
// ====================================================================================================================
// FlexisipAuthModuleBase class
// ====================================================================================================================
FlexisipAuthModuleBase::FlexisipAuthModuleBase(su_root_t *root, const std::string &domain, const std::string &algo):
AuthModule(root,
AUTHTAG_REALM(domain.c_str()),
AUTHTAG_OPAQUE("+GNywA=="),
AUTHTAG_FORBIDDEN(1),
AUTHTAG_ALLOW("ACK CANCEL BYE"),
AUTHTAG_ALGORITHM(algo.c_str()),
TAG_END()
),
mDisableQOPAuth(true) {
}
FlexisipAuthModuleBase::FlexisipAuthModuleBase(su_root_t *root, const std::string &domain, const std::string &algo, int nonceExpire):
AuthModule(root,
AUTHTAG_REALM(domain.c_str()),
AUTHTAG_OPAQUE("+GNywA=="),
AUTHTAG_QOP("auth"),
AUTHTAG_FORBIDDEN(1),
AUTHTAG_ALLOW("ACK CANCEL BYE"),
AUTHTAG_ALGORITHM(algo.c_str()),
AUTHTAG_EXPIRES(nonceExpire),
AUTHTAG_NEXT_EXPIRES(nonceExpire),
TAG_END()
) {
mNonceStore.setNonceExpires(nonceExpire);
}
void FlexisipAuthModuleBase::onCheck(AuthStatus &as, msg_auth_t *au, auth_challenger_t const *ach) {
auto &authStatus = dynamic_cast<FlexisipAuthStatus &>(as);
as.allow(as.allow() || auth_allow_check(mAm, as.getPtr()) == 0);
if (as.realm()) {
/* Workaround for old linphone client that don't check whether algorithm is MD5 or SHA256.
* They then answer for both, but the first one for SHA256 is of course wrong.
* We workaround by selecting the second digest response.
*/
if (au && au->au_next) {
auth_response_t r;
memset(&r, 0, sizeof(r));
r.ar_size = sizeof(r);
auth_digest_response_get(as.home(), &r, au->au_next->au_params);
if (r.ar_algorithm == NULL || !strcasecmp(r.ar_algorithm, "MD5")) {
au = au->au_next;
}
}
/* After auth_digest_credentials, there is no more au->au_next. */
au = auth_digest_credentials(au, as.realm(), mAm->am_opaque);
} else
au = NULL;
if (as.allow()) {
LOGD("%s: allow unauthenticated %s", __func__, as.method());
as.status(0), as.phrase(nullptr);
as.match(reinterpret_cast<msg_header_t *>(au));
return;
}
if (au) {
SLOGD << "Searching for auth digest response for this proxy";
msg_auth_t *matched_au = ModuleToolbox::findAuthorizationForRealm(as.home(), au, as.realm());
if (matched_au)
au = matched_au;
as.match(reinterpret_cast<msg_header_t *>(au));
checkAuthHeader(authStatus, au, ach);
} else {
/* There was no realm or credentials, send challenge */
SLOGD << __func__ << ": no credentials matched realm or no realm";
auth_challenge_digest(mAm, as.getPtr(), ach);
mNonceStore.insert(as.response());
// Retrieve the password in the hope it will be in cache when the remote UAC
// sends back its request; this time with the expected authentication credentials.
if (mImmediateRetrievePass) {
loadPassword(authStatus);
}
finish(authStatus);
return;
}
}
void FlexisipAuthModuleBase::onChallenge(AuthStatus &as, auth_challenger_t const *ach) {
auth_challenge_digest(mAm, as.getPtr(), ach);
}
void FlexisipAuthModuleBase::onCancel(AuthStatus &as) {
auth_cancel_default(mAm, as.getPtr());
}
/**
* return true if the event is terminated
*/
void FlexisipAuthModuleBase::finish(FlexisipAuthStatus &as) {
if ((as.usedAlgo().size() > 1) && (as.status() == 401)) {
auto *response = reinterpret_cast<msg_auth_t *>(msg_header_copy(as.home(), as.response()));
msg_header_remove_param(reinterpret_cast<msg_common_t *>(as.response()), "algorithm=MD5");
msg_header_replace_item(as.home(), reinterpret_cast<msg_common_t *>(as.response()), "algorithm=SHA-256");
reinterpret_cast<msg_auth_t *>(as.response())->au_next = response;
}
as.getPtr()->as_callback(as.magic(), as.getPtr());
}
void FlexisipAuthModuleBase::onError(FlexisipAuthStatus &as) {
if (as.status() != 0) {
as.status(500);
as.phrase("Internal error");
as.response(nullptr);
}
finish(as);
}
// ====================================================================================================================
/*
* Flexisip, a flexible SIP proxy server with media capabilities.
* Copyright (C) 2018 Belledonne Communications SARL, All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <vector>
#include <sofia-sip/auth_digest.h>
#include <sofia-sip/auth_module.h>
#include <sofia-sip/msg_types.h>
#include <sofia-sip/su_wait.h>
#include "auth-module.hh"
#include "flexisip-auth-status.hh"
#include "nonce-store.hh"
/**
* @brief Base class for all authentication modules used by Flexisip.
*
* This implementation of AuthModule allows to do HTTP-like authentication
* of SIP requests as described in RFC 3261 §22.
*/
class FlexisipAuthModuleBase : public AuthModule {
public:
/**
* @brief Instantiate a new authentication module without QOP authentication feature.
* @param[in] root Event loop which the module will be working on.
* @param[in] domain The domain name which the module is in charge of.
* @param[in] algo The digest algorithm to use. Only "MD5" and "SHA-256" are supported.
*/
FlexisipAuthModuleBase(su_root_t *root, const std::string &domain, const std::string &algo);
/**
* @brief Instantiate a new authentication module with QOP authentication feature enabled.
* @param[in] nonceExpire Validity period for a nonce in seconds.
*/
FlexisipAuthModuleBase(su_root_t *root, const std::string &domain, const std::string &algo, int nonceExpire);
~FlexisipAuthModuleBase() override = default;
NonceStore &nonceStore() {return mNonceStore;}
protected:
/**
* This method is called each time the module want to authenticate an Authorization header.
* The result of the authentication must be store in 'status' attribute of 'as' parameter as
* described in documentation of auth_mod_verify() function.
*
* @param[in,out] as The context on the authentication. It is also used to return the result.
* @param[in] credentials The authorization header to validate.
*/
virtual void checkAuthHeader(FlexisipAuthStatus &as, msg_auth_t *credentials, auth_challenger_t const *ach) = 0;
/**
* This function is called when the module is validating a request that doesn't have any authorization header.
* It allows implementations based on password database to load the password in cache in order to be already fetched
* once the user send a request containing the Authorization header. The default implementation of this method does nothing.
*/
virtual void loadPassword(const FlexisipAuthStatus &as) = 0;
void finish(FlexisipAuthStatus &as);
void onError(FlexisipAuthStatus &as);
NonceStore mNonceStore;
bool mDisableQOPAuth = false;
bool mImmediateRetrievePass = true;
private:
void onCheck(AuthStatus &as, msg_auth_t *credentials, auth_challenger_t const *ach) override;
void onChallenge(AuthStatus &as, auth_challenger_t const *ach) override;
void onCancel(AuthStatus &as) override;
};
This diff is collapsed.
/*
* Flexisip, a flexible SIP proxy server with media capabilities.
* Copyright (C) 2018 Belledonne Communications SARL, All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <vector>
#include <sofia-sip/auth_digest.h>
#include <sofia-sip/auth_module.h>
#include <sofia-sip/msg_types.h>
#include <sofia-sip/su_wait.h>
#include "auth-module.hh"
#include "authdb.hh"
#include "flexisip-auth-module-base.hh"
#include "flexisip-auth-status.hh"
#include "nonce-store.hh"
/**
* Authentication module using a user database to validate the Authorization header.
*/
class FlexisipAuthModule : public FlexisipAuthModuleBase {
public:
FlexisipAuthModule(su_root_t *root, const std::string &domain, const std::string &algo): FlexisipAuthModuleBase(root, domain, algo) {}
FlexisipAuthModule(su_root_t *root, const std::string &domain, const std::string &algo, int nonceExpire): FlexisipAuthModuleBase(root, domain, algo, nonceExpire) {}
~FlexisipAuthModule() override = default;
private:
class AuthenticationListener : public AuthDbListener {
public:
AuthenticationListener(FlexisipAuthModule &am, FlexisipAuthStatus &as, const auth_challenger_t &ach, const auth_response_t &ar): mAm(am), mAs(as), mAch(ach), mAr(ar) {}
~AuthenticationListener() override = default;
FlexisipAuthStatus &authStatus() const {return mAs;}
const auth_challenger_t &challenger() const {return mAch;}
auth_response_t *response() {return &mAr;}
std::string password() const {return mPassword;}
AuthDbResult result() const {return mResult;}
void onResult(AuthDbResult result, const std::string &passwd) override;
void onResult(AuthDbResult result, const std::vector<passwd_algo_t> &passwd) override;
void finishVerifyAlgos(const std::vector<passwd_algo_t> &pass) override;
private:
static void main_thread_async_response_cb(su_root_magic_t *rm, su_msg_r msg, void *u);
friend class Authentication;
FlexisipAuthModule &mAm;
FlexisipAuthStatus &mAs;
const auth_challenger_t &mAch;
auth_response_t mAr;
AuthDbResult mResult;
std::string mPassword;
};
void checkAuthHeader(FlexisipAuthStatus &as, msg_auth_t *credentials, auth_challenger_t const *ach) override;
void loadPassword(const FlexisipAuthStatus &as) override;
void processResponse(AuthenticationListener &listener);
void checkPassword(FlexisipAuthStatus &as, const auth_challenger_t &ach, auth_response_t &ar, const char *password);
int checkPasswordForAlgorithm(FlexisipAuthStatus &as, auth_response_t &ar, const char *password);
int checkPasswordMd5(FlexisipAuthStatus &as, auth_response_t &ar, const char *passwd);
static std::string auth_digest_a1_for_algorithm(const auth_response_t *ar, const std::string &secret);
static std::string auth_digest_a1sess_for_algorithm(const auth_response_t *ar, const std::string &ha1);
static std::string auth_digest_response_for_algorithm(::auth_response_t *ar, char const *method_name, void const *data, isize_t dlen, const std::string &ha1);
static std::string sha256(const std::string &data);
static std::string sha256(const void *data, size_t len);
static std::string toString(const std::vector<uint8_t> &data);
};
/*
* Flexisip, a flexible SIP proxy server with media capabilities.
* Copyright (C) 2018 Belledonne Communications SARL, All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/