From 62898a7d19c507dc992b032010f030686413223a Mon Sep 17 00:00:00 2001 From: Tristan Matthews <tristan.matthews@savoirfairelinux.com> Date: Mon, 30 Jul 2012 17:01:19 -0400 Subject: [PATCH] * #14077: sip: check if server address in SIP transactions is our proxy --- daemon/src/managerimpl.cpp | 13 +++++++++- daemon/src/sip/sip_utils.cpp | 45 ++++++++++++++++++++++++++++++++++ daemon/src/sip/sip_utils.h | 4 +++ daemon/src/sip/sipaccount.cpp | 12 ++++++++- daemon/src/sip/sipaccount.h | 1 + daemon/src/sip/sipvoiplink.cpp | 33 +------------------------ 6 files changed, 74 insertions(+), 34 deletions(-) diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp index 41e42e4d5e..2a2e1db187 100644 --- a/daemon/src/managerimpl.cpp +++ b/daemon/src/managerimpl.cpp @@ -2669,7 +2669,8 @@ ManagerImpl::getAccount(const std::string& accountID) return accountMap_[SIPAccount::IP2IP_PROFILE]; } -std::string ManagerImpl::getAccountIdFromNameAndServer(const std::string& userName, const std::string& server) const +std::string +ManagerImpl::getAccountIdFromNameAndServer(const std::string& userName, const std::string& server) const { DEBUG("username = %s, server = %s", userName.c_str(), server.c_str()); // Try to find the account id from username and server name by full match @@ -2703,6 +2704,16 @@ std::string ManagerImpl::getAccountIdFromNameAndServer(const std::string& userNa } } + // We failed! Then only match the hostname against our proxy + for (AccountMap::const_iterator iter = accountMap_.begin(); iter != accountMap_.end(); ++iter) { + SIPAccount *account = dynamic_cast<SIPAccount *>(iter->second); + + if (account and account->isEnabled() and account->proxyMatch(server)) { + DEBUG("Matching account id in request with proxy %s", server.c_str()); + return iter->first; + } + } + DEBUG("Username %s or server %s doesn't match any account, using IP2IP", userName.c_str(), server.c_str()); return ""; } diff --git a/daemon/src/sip/sip_utils.cpp b/daemon/src/sip/sip_utils.cpp index bdcd57542a..d64a2f6c2d 100644 --- a/daemon/src/sip/sip_utils.cpp +++ b/daemon/src/sip/sip_utils.cpp @@ -42,6 +42,13 @@ #include <pj/list.h> #include "sip_utils.h" +// for resolveDns +#include <list> +#include <netdb.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + std::string sip_utils::fetchHeaderValue(pjsip_msg *msg, const std::string &field) { @@ -124,3 +131,41 @@ sip_utils::stripSipUriPrefix(std::string& sipUri) if (found != std::string::npos) sipUri.erase(found); } + +/** + * This function looks for '@' and replaces the second part with the corresponding ip address (when possible) + */ +std::string +sip_utils::resolveDns(const std::string &url) +{ + size_t pos; + if ((pos = url.find("@")) == std::string::npos) + return url; + + const std::string hostname = url.substr(pos + 1); + + std::list<std::string> ipList(resolveServerDns(hostname)); + if (not ipList.empty() and ipList.front().size() > 7 ) + return url.substr(0, pos + 1) + ipList.front(); + else + return hostname; +} + +/** + * This function finds the list of IP addresses (when possible) for a given server + */ +std::list<std::string> +sip_utils::resolveServerDns(const std::string &server) +{ + struct hostent *he; + std::list<std::string> ipList; + + if ((he = gethostbyname(server.c_str())) == NULL) + return ipList; + struct in_addr **addr_list = (struct in_addr **) he->h_addr_list; + + for (int i = 0; addr_list[i] != NULL; ++i) + ipList.push_back(inet_ntoa(*addr_list[i])); + + return ipList; +} diff --git a/daemon/src/sip/sip_utils.h b/daemon/src/sip/sip_utils.h index 4d430af97c..99c56002cf 100644 --- a/daemon/src/sip/sip_utils.h +++ b/daemon/src/sip/sip_utils.h @@ -33,6 +33,7 @@ #define SIP_UTILS_H_ #include <string> +#include <list> #include <pjsip/sip_msg.h> @@ -50,6 +51,9 @@ namespace sip_utils { void stripSipUriPrefix(std::string& sipUri); std::string parseDisplayName(const char * buffer); + + std::string resolveDns(const std::string &url); + std::list<std::string> resolveServerDns(const std::string &server); } #endif // SIP_UTILS_H_ diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp index 5e04cb4ec8..b578bbda4b 100644 --- a/daemon/src/sip/sipaccount.cpp +++ b/daemon/src/sip/sipaccount.cpp @@ -36,6 +36,7 @@ #include "account_schema.h" #include "sipaccount.h" +#include "sip_utils.h" #include "sipvoiplink.h" #include "config/yamlnode.h" #include "config/yamlemitter.h" @@ -43,7 +44,8 @@ #include "manager.h" #include <pwd.h> #include <sstream> -#include <stdlib.h> +#include <algorithm> +#include <cstdlib> #ifdef SFL_VIDEO #include "video/libav_utils.h" @@ -794,6 +796,14 @@ bool SIPAccount::hostnameMatch(const std::string& hostname) const return hostname == hostname_; } +bool SIPAccount::proxyMatch(const std::string& hostname) const +{ + if (hostname == serviceRoute_) + return true; + const std::list<std::string> ipList(sip_utils::resolveServerDns(serviceRoute_)); + return std::find(ipList.begin(), ipList.end(), hostname) != ipList.end(); +} + std::string SIPAccount::getLoginName() { struct passwd * user_info = getpwuid(getuid()); diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h index cb4292f3d0..6829909ced 100644 --- a/daemon/src/sip/sipaccount.h +++ b/daemon/src/sip/sipaccount.h @@ -250,6 +250,7 @@ class SIPAccount : public Account { bool fullMatch(const std::string& username, const std::string& hostname) const; bool userMatch(const std::string& username) const; bool hostnameMatch(const std::string& hostname) const; + bool proxyMatch(const std::string& hostname) const; /** * Registration flag diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp index 65249ec98c..b8b00713e8 100644 --- a/daemon/src/sip/sipvoiplink.cpp +++ b/daemon/src/sip/sipvoiplink.cpp @@ -725,43 +725,12 @@ bool isValidIpAddress(const std::string &address) return result != 0; } -/** - * This function look for '@' and replace the second part with the corresponding ip address (when possible) - */ -std::string resolvDns(const std::string& url) -{ - size_t pos; - if ((pos = url.find("@")) == std::string::npos) { - return url; - } - std::string hostname = url.substr(pos+1); - - int i; - struct hostent *he; - struct in_addr **addr_list; - - if ((he = gethostbyname(hostname.c_str())) == NULL) { - return url; - } - - addr_list = (struct in_addr **)he->h_addr_list; - std::list<std::string> ipList; - - for(i = 0; addr_list[i] != NULL; i++) { - ipList.push_back(inet_ntoa(*addr_list[i])); - } - - if (ipList.size() > 0 && ipList.front().size() > 7 ) - return url.substr(0,pos+1)+ipList.front(); - else - return hostname; -} Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toUrl) { DEBUG("New outgoing call to %s", toUrl.c_str()); std::string toCpy = toUrl; - std::string resolvedUrl = resolvDns(toUrl); + std::string resolvedUrl = sip_utils::resolveDns(toUrl); DEBUG("URL resolved to %s", resolvedUrl.c_str()); sip_utils::stripSipUriPrefix(toCpy); -- GitLab