Commit 419bc875 authored by François Grisez's avatar François Grisez

Add '$uuid' variable to 'ExternalAuthentication/remote-uri' syntax

parent 566ee18f
Pipeline #4714 passed with stages
in 44 minutes and 55 seconds
......@@ -400,8 +400,7 @@ class RegistrarDb {
void unsubscribeLocalRegExpire(LocalRegExpireListener *listener) {
mLocalRegExpire->unsubscribe(listener);
}
static std::string uniqueIdToGr(const std::string &uid);
static std::string grToUniqueId(const std::string &gr);
protected:
class LocalRegExpire {
std::map<std::string, time_t> mRegMap;
......
......@@ -26,6 +26,8 @@
#include <flexisip/configmanager.hh>
#include "utils/uri-utils.hh"
using namespace flexisip;
using namespace std;
......@@ -217,7 +219,7 @@ void ConferenceServer::bindChatRoom (
sip_contact_t* sipContact = sip_contact_create(mHome.home(),
reinterpret_cast<const url_string_t*>(url_make(mHome.home(), contact.c_str())),
su_strdup(mHome.home(), ("+sip.instance=" + RegistrarDb::grToUniqueId(gruu) ).c_str()), nullptr);
su_strdup(mHome.home(), ("+sip.instance=" + UriUtils::grToUniqueId(gruu) ).c_str()), nullptr);
url_t *from = url_make(mHome.home(), bindingUrl.c_str());
parameter.callId = gruu;
......
......@@ -97,6 +97,7 @@ std::map<std::string, std::string> ExternalAuthModule::extractParameters(const S
params["method"] = StringUtils::strip(as.method(), '"');
params["from"] = StringUtils::strip(as.fromHeader(), '"');
params["sip-instance"] = StringUtils::strip(as.sipInstance(), '"');
params["uuid"] = as.uuid();
params["domain"] = StringUtils::strip(as.domain(), '"');
return params;
}
......
......@@ -58,12 +58,17 @@ public:
void sipInstance(const std::string &val) {mSipInstance = val;}
void sipInstance(std::string &&val) {mSipInstance = std::move(val);}
const std::string &uuid() const {return mUUID;}
void uuid(const std::string &uuid) {mUUID = uuid;}
void uuid(std::string &uuid) {mUUID = std::move(uuid);}
private:
std::string mReasonHeader; /**< [out] Reason header returned by the HTTP server on authentication failure. */
std::string mPAssertedIdentity; /**< [out] PAssertIdentity header returned by the HTTP server on authentication success. */
std::string mFromHeader; /**< [in] Value of From header of the request. */
std::string mDomain; /**< [in] Domain of the From header. */
std::string mSipInstance; /**< [in] Value of the +sip.instance parameter from Contact header. */
std::string mUUID; /**< [in] UUID of the application that is trying to authenticate. */
};
ExternalAuthModule(su_root_t *root, const std::string &domain, const std::string &algo);
......
......@@ -27,6 +27,9 @@
#include <flexisip/plugin.hh>
#include "utils/string-utils.hh"
#include "utils/uri-utils.hh"
#include "module-external-authentication.hh"
using namespace std;
......@@ -52,6 +55,9 @@ void ModuleExternalAuthentication::onDeclare(GenericStruct *mc) {
"\t* $from: the value of the request's 'From:' header\n"
"\t* $domain: the domain name extracted from the From header's URI\n"
"\t* all the parameters available in the Authorization header. Ex: $realm, $nonce, $username, ...\n"
"\t* $uuid: the UUID of the user agent whose request is being challenged. The UUID is gotten from "
"the 'gr' parameter of the contact URI or, if not present, from the '+sip.instance' parameter. "
"If neither 'gr' nor '+sip.instance' parameters are present, then $uuid is be replaced by an empty string."
"\n"
"Ex: https://$realm.example.com/auth?from=$from&cnonce=$cnonce&username=$username",
""
......@@ -90,6 +96,19 @@ FlexisipAuthStatus *ModuleExternalAuthentication::createAuthStatus(const std::sh
if (sip->sip_contact) {
const char *sipInstance = msg_header_find_param(reinterpret_cast<msg_common_t *>(sip->sip_contact), "+sip.instance");
as->sipInstance(sipInstance ? sipInstance : "");
string uuid;
if (url_has_param(sip->sip_contact->m_url, "gr")) {
uuid = UriUtils::getParamValue(sip->sip_contact->m_url->url_params, "gr");
} else {
uuid = UriUtils::uniqueIdToGr(as->sipInstance());
}
try {
uuid = StringUtils::removePrefix(uuid, "urn:uuid:");
as->uuid(move(uuid));
} catch (const invalid_argument &e) {
SLOGE << "ExernalAuthentication: error while getting UUID: " << e.what();
}
}
return as;
......
......@@ -36,6 +36,7 @@
#include "recordserializer.hh"
#include <flexisip/module.hh>
#include "utils/string-utils.hh"
#include "utils/uri-utils.hh"
using namespace std;
using namespace flexisip;
......@@ -1071,11 +1072,11 @@ void RegistrarDb::fetch(const url_t *url, const shared_ptr<ContactUpdateListener
return;
}
if(url_has_param(url, "gr")) {
char buffer[255] = {0};
if (url_param(url->url_params, "gr", buffer, sizeof(buffer)-1) > 0) {
doFetchInstance(url, grToUniqueId(buffer), recursive
? make_shared<RecursiveRegistrarDbListener>(this, listener, url)
: listener);
string gr = UriUtils::getParamValue(url->url_params, "gr");
if (!gr.empty()) {
doFetchInstance(url, UriUtils::grToUniqueId(gr), recursive
? make_shared<RecursiveRegistrarDbListener>(this, listener, url)
: listener);
return;
}
}
......@@ -1128,7 +1129,7 @@ void RegistrarDb::bind(const sip_t *sip, const BindingParameters &parameter, con
if (msg_params_find(sip->sip_supported->k_items, "gruu") != nullptr){
const char *instance_param = msg_params_find(sip->sip_contact->m_params, "+sip.instance");
if (instance_param) {
string gr = uniqueIdToGr(instance_param);
string gr = UriUtils::uniqueIdToGr(instance_param);
if (!gr.empty()){/* assign a public gruu address to this contact */
msg_header_replace_param(home.home(), (msg_common_t *) sip->sip_contact,
su_sprintf(home.home(), "pub-gruu=\"%s;gr=%s\"", url_as_string(home.home(), sip->sip_from->a_url), gr.c_str() ) );
......@@ -1175,27 +1176,6 @@ void RegistrarDb::bind(const url_t *from, const sip_contact_t *contact, const Bi
msg_unref(msg);
}
/* Transforms the unique id to a "gr" parameter value. */
string RegistrarDb::uniqueIdToGr(const string &uid){
string ret;
size_t begin = uid.find('<');
if (begin != string::npos){
size_t end = uid.find('>', begin + 1);
if (end != string::npos){
begin++; //skip '<'
ret = uid.substr(begin, end - begin);
}
}
return ret;
}
string RegistrarDb::grToUniqueId(const string &gr){
ostringstream uid;
uid << "\"<" << gr << ">\"";
return uid.str();
}
class AgregatorRegistrarDbListener : public ContactUpdateListener {
private:
shared_ptr<ContactUpdateListener> mOriginalListener;
......
......@@ -17,6 +17,7 @@
*/
#include <cstring>
#include <stdexcept>
#include "string-utils.hh"
......@@ -53,3 +54,12 @@ void StringUtils::strip(std::string::const_iterator &start, std::string::const_i
start++;
end--;
}
std::string StringUtils::removePrefix(const std::string &str, const std::string &prefix) {
if (str.compare(0, prefix.size(), prefix) != 0) {
ostringstream os;
os << "'" << prefix << "' is not a prefix of '" << str << "'";
throw invalid_argument(os.str());
}
return str.substr(prefix.size());
}
......@@ -33,6 +33,13 @@ public:
static std::string strip(const std::string &str, char c);
static void strip(std::string::const_iterator &start, std::string::const_iterator &end, char c);
/**
* @brief Check whether the string 'str' starts with 'prefix' and returned the subsequent
* part of the string.
* @throw invalid_argument when 'str' doesn't start with 'prefix'.
*/
static std::string removePrefix(const std::string &str, const std::string &prefix);
template <class Iterable>
static std::string toString(const Iterable &iterable) {
std::ostringstream os;
......
......@@ -16,6 +16,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sstream>
#include <stdexcept>
#include <vector>
#include <sofia-sip/url.h>
......@@ -41,3 +43,30 @@ std::string UriUtils::unescape(const char *str, size_t n) {
unescapedStr.resize(n);
return unescapedStr;
}
std::string UriUtils::getParamValue(const char *paramList, const char *paramName) {
string value(_bufferSize, '\0');
isize_t valueSize = url_param(paramList, paramName, &value[0], value.size());
if (valueSize == 0) throw out_of_range(string("\'") + paramName + "\' not found");
value.resize(valueSize-1);
return value;
}
std::string UriUtils::uniqueIdToGr(const std::string &uid) {
string ret;
size_t begin = uid.find('<');
if (begin != string::npos) {
size_t end = uid.find('>', begin + 1);
if (end != string::npos) {
begin++; //skip '<'
ret = uid.substr(begin, end - begin);
}
}
return ret;
}
std::string UriUtils::grToUniqueId(const std::string &gr) {
ostringstream uid;
uid << "\"<" << gr << ">\"";
return uid.str();
}
......@@ -61,6 +61,35 @@ public:
static std::string unescape(const char *str) {return unescape(str, strlen(str));}
static std::string unescape(const std::string &str) {return unescape(str.c_str(), str.size());}
/**
* @brief Return the value of a given param from a string that contains a list
* of 'param=value' elements separated by semi-colon character.
* @param paramList The string containing the list of parameter.
* @param paramName The name of the parameter whose value is to be gotten.
* @return The value of the parameter. If the parameter exists but has no value, then the return string is empty.
* @throw std::out_of_range The given paramter could not be found.
*/
static std::string getParamValue(const char *paramList, const char *paramName);
static std::string getParamFromParamList(const std::string &paramList, const std::string &paramName) {return getParamValue(paramList.c_str(), paramName.c_str());}
/**
* @brief Translate a UUID given by +sip.instance parameter into an
* UUID ready for GRUU generation.
*
* In other words, this function strips the input string from
* double-quotes and then '< >' characters. The return string is
* empty if the input string doesn't match the expected format.
*/
static std::string uniqueIdToGr(const std::string &uid);
/**
* @brief Format an UUID extracted for a GRUU into
* a string ready to used as vaule of +sip.instance parameter.
*/
static std::string grToUniqueId(const std::string &gr);
private:
static std::string unescape(const char *str, size_t n);
static const size_t _bufferSize = 255;
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment