XRootD
Loading...
Searching...
No Matches
XrdOucUtils.cc File Reference
#include <cctype>
#include <grp.h>
#include <cstdio>
#include <list>
#include <vector>
#include <unordered_set>
#include <algorithm>
#include <charconv>
#include <random>
#include <regex.h>
#include <fcntl.h>
#include <math.h>
#include <pwd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <map>
#include <iomanip>
#include "XrdNet/XrdNetUtils.hh"
#include "XrdOuc/XrdOucCRC.hh"
#include "XrdOuc/XrdOucEnv.hh"
#include "XrdOuc/XrdOucSHA3.hh"
#include "XrdOuc/XrdOucStream.hh"
#include "XrdOuc/XrdOucString.hh"
#include "XrdOuc/XrdOucUtils.hh"
#include "XrdOuc/XrdOucPrivateUtils.hh"
#include "XrdSys/XrdSysE2T.hh"
#include "XrdSys/XrdSysError.hh"
#include "XrdSys/XrdSysPlatform.hh"
#include "XrdSys/XrdSysPthread.hh"
Include dependency graph for XrdOucUtils.cc:

Go to the source code of this file.

Macros

#define ENODATA   ENOATTR
#define SHFT(k)
#define SHFT(k, m)

Functions

static int from_hex (char c)
static bool is_rfc3986_unreserved (unsigned char c)
static bool is_token_character (int c)
std::string obfuscateAuth (const std::string &input)
void splitHostCgi (std::string_view target, std::string &host, std::string &cgi)
void stripCgi (std::string &url, const std::unordered_set< std::string > &cgiKeys)
void stripCgi (XrdOucString &url, const std::unordered_set< std::string > &cgiKeys)

Macro Definition Documentation

◆ ENODATA

#define ENODATA   ENOATTR

Definition at line 69 of file XrdOucUtils.cc.

◆ SHFT [1/2]

#define SHFT ( k)
Value:
if (n >= (1ULL << k)) { i += k; n >>= k; }

Referenced by XrdOucUtils::Log10(), and XrdOucUtils::Log2().

◆ SHFT [2/2]

#define SHFT ( k,
m )
Value:
if (n >= m) { i += k; n /= m; }

Function Documentation

◆ from_hex()

int from_hex ( char c)
static

Definition at line 1700 of file XrdOucUtils.cc.

1701{
1702 if (c >= '0' && c <= '9') return c - '0';
1703 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
1704 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
1705 return -1;
1706}

Referenced by XrdOucUtils::UrlDecode().

Here is the caller graph for this function:

◆ is_rfc3986_unreserved()

bool is_rfc3986_unreserved ( unsigned char c)
static

Definition at line 1669 of file XrdOucUtils.cc.

1670{
1671 return std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~';
1672}

Referenced by XrdOucUtils::UrlEncode().

Here is the caller graph for this function:

◆ is_token_character()

bool is_token_character ( int c)
static

Returns a boolean indicating whether 'c' is a valid token character or not. See https://datatracker.ietf.org/doc/html/rfc6750#section-2.1 for details.

Definition at line 1615 of file XrdOucUtils.cc.

1616{
1617 if (isalnum(c))
1618 return true;
1619
1620 static constexpr char token_chars[] = "-._~+/=:%";
1621
1622 for (char ch : token_chars)
1623 if (c == ch)
1624 return true;
1625
1626 return false;
1627}

Referenced by obfuscateAuth(), and stripCgi().

Here is the caller graph for this function:

◆ obfuscateAuth()

std::string obfuscateAuth ( const std::string & input)

This function obfuscates away authz= cgi elements and/or HTTP authorization headers from URL or other log line strings which might contain them.

Parameters
inputthe string to obfuscate
Returns
the string with token values obfuscated

Definition at line 1637 of file XrdOucUtils.cc.

1638{
1639 static const regex_t auth_regex = []() {
1640 constexpr char re[] =
1641 "(authz=|(transferheader)?(www-|proxy-)?auth(orization|enticate)([[:space:]]*:[[:space:]]*|[[:space:]]+))"
1642 "(Bearer([[:space:]]|%20)?(token([[:space:]]|%20)?)?)?";
1643
1644 regex_t regex;
1645
1646 if (regcomp(&regex, re, REG_EXTENDED | REG_ICASE) != 0)
1647 throw std::runtime_error("Failed to compile regular expression");
1648
1649 return regex;
1650 }();
1651
1652 regmatch_t match;
1653 size_t offset = 0;
1654 std::string redacted;
1655 const char *const text = input.c_str();
1656
1657 while (regexec(&auth_regex, text + offset, 1, &match, 0) == 0) {
1658 redacted.append(text + offset, match.rm_eo).append("REDACTED");
1659
1660 offset += match.rm_eo;
1661
1662 while (offset < input.size() && is_token_character(input[offset]))
1663 ++offset;
1664 }
1665
1666 return redacted.append(text + offset);
1667}
static bool is_token_character(int c)

References is_token_character().

Referenced by XrdPfc::Cache::Attach(), XrdClHttp::HeaderBuilder::Build(), XrdPosixXrootd::Close(), XrdPosixFile::DelayedDestroy(), XrdPosixFile::DelayedDestroy(), XrdPosixPrepIO::Disable(), XrdPssSys::FSctl(), XrdPssCks::Get(), XrdCl::URL::GetObfuscatedURL(), XrdCl::Utils::LogPropertyList(), main(), XrdPssSys::Mkdir(), XrdPssFile::Open(), XrdPssDir::Opendir(), XrdCl::CopyProcess::Prepare(), XrdHttpProtocol::Process(), XrdHttpReq::ProcessHTTPReq(), XrdPssSys::Remdir(), XrdPssSys::Rename(), XrdCl::Message::SetDescription(), XrdPssSys::Stat(), XrdPssSys::Truncate(), and XrdPssSys::Unlink().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ splitHostCgi()

void splitHostCgi ( std::string_view target,
std::string & host,
std::string & cgi )

Split a "host[?cgi]" string at its first '?'.

Parameters
targetthe "host[?cgi]" string to split
hostoutput: the portion before the first '?', or the whole string when target contains no '?'
cgioutput: the first '?' and everything after it (so it begins with '?'), or empty when target contains no '?'

Definition at line 1778 of file XrdOucUtils.cc.

1780{
1781 const size_t q = target.find('?');
1782 if (q == std::string::npos) {host.assign(target); cgi.clear();}
1783 else {host.assign(target.data(), q);
1784 cgi.assign(target.data() + q, target.size() - q);
1785 }
1786}

Referenced by XrdXrootdRedirHelper::Redirect().

Here is the caller graph for this function:

◆ stripCgi() [1/2]

void stripCgi ( std::string & url,
const std::unordered_set< std::string > & cgiKeys )

Strip selected CGI elements (e.g. "authz=...") from a string/URL.

Parameters
urlthe string/URL to sanitize
cgiKeysCGI parameter names to remove (without the trailing '=')

Definition at line 1744 of file XrdOucUtils.cc.

1745{
1746 for (const auto &key : cgiKeys) {
1747 if (key.empty())
1748 continue;
1749
1750 const std::string needle = key + "=";
1751 size_t spos = 0, epos = 0;
1752
1753 while ((spos = url.find(needle, spos)) != std::string::npos) {
1754 epos = spos;
1755 while (epos < url.size() && is_token_character(url[epos]))
1756 ++epos;
1757 url.erase(spos, epos - spos);
1758 }
1759 }
1760
1761 // If a stripped CGI was the first element, remove the extra &
1762 size_t spos = 0;
1763 if ((spos = url.find("?&")) != std::string::npos)
1764 url.erase(spos + 1, 1);
1765
1766 // If stripping removed the only query parameter, remove the dangling ?
1767 if (!url.empty() && url.back() == '?')
1768 url.pop_back();
1769}

References is_token_character().

Referenced by XrdHttpReq::Redir(), and stripCgi().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stripCgi() [2/2]

void stripCgi ( XrdOucString & url,
const std::unordered_set< std::string > & cgiKeys )

Definition at line 1771 of file XrdOucUtils.cc.

1772{
1773 std::string tmp = url.c_str();
1774 stripCgi(tmp, cgiKeys);
1775 url = tmp.c_str();
1776}
void stripCgi(std::string &url, const std::unordered_set< std::string > &cgiKeys)
const char * c_str() const

References XrdOucString::c_str(), and stripCgi().

Here is the call graph for this function: