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 1673 of file XrdOucUtils.cc.

1674{
1675 if (c >= '0' && c <= '9') return c - '0';
1676 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
1677 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
1678 return -1;
1679}

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 1642 of file XrdOucUtils.cc.

1643{
1644 return std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~';
1645}

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 1588 of file XrdOucUtils.cc.

1589{
1590 if (isalnum(c))
1591 return true;
1592
1593 static constexpr char token_chars[] = "-._~+/=:%";
1594
1595 for (char ch : token_chars)
1596 if (c == ch)
1597 return true;
1598
1599 return false;
1600}

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 1610 of file XrdOucUtils.cc.

1611{
1612 static const regex_t auth_regex = []() {
1613 constexpr char re[] =
1614 "(authz=|(transferheader)?(www-|proxy-)?auth(orization|enticate)[[:space:]]*:[[:space:]]*)"
1615 "(Bearer([[:space:]]|%20)?(token([[:space:]]|%20)?)?)?";
1616
1617 regex_t regex;
1618
1619 if (regcomp(&regex, re, REG_EXTENDED | REG_ICASE) != 0)
1620 throw std::runtime_error("Failed to compile regular expression");
1621
1622 return regex;
1623 }();
1624
1625 regmatch_t match;
1626 size_t offset = 0;
1627 std::string redacted;
1628 const char *const text = input.c_str();
1629
1630 while (regexec(&auth_regex, text + offset, 1, &match, 0) == 0) {
1631 redacted.append(text + offset, match.rm_eo).append("REDACTED");
1632
1633 offset += match.rm_eo;
1634
1635 while (offset < input.size() && is_token_character(input[offset]))
1636 ++offset;
1637 }
1638
1639 return redacted.append(text + offset);
1640}
static bool is_token_character(int c)

References is_token_character().

Referenced by XrdPfc::Cache::Attach(), XrdPosixXrootd::Close(), XrdPosixFile::DelayedDestroy(), XrdPosixFile::DelayedDestroy(), XrdPosixPrepIO::Disable(), XrdCl::URL::FromString(), XrdPssSys::FSctl(), XrdPssCks::Get(), XrdCl::URL::GetObfuscatedURL(), XrdCl::Utils::LogPropertyList(), main(), XrdPssSys::Mkdir(), XrdPssFile::Open(), XrdPssDir::Opendir(), 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 1751 of file XrdOucUtils.cc.

1753{
1754 const size_t q = target.find('?');
1755 if (q == std::string::npos) {host.assign(target); cgi.clear();}
1756 else {host.assign(target.data(), q);
1757 cgi.assign(target.data() + q, target.size() - q);
1758 }
1759}

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 1717 of file XrdOucUtils.cc.

1718{
1719 for (const auto &key : cgiKeys) {
1720 if (key.empty())
1721 continue;
1722
1723 const std::string needle = key + "=";
1724 size_t spos = 0, epos = 0;
1725
1726 while ((spos = url.find(needle, spos)) != std::string::npos) {
1727 epos = spos;
1728 while (epos < url.size() && is_token_character(url[epos]))
1729 ++epos;
1730 url.erase(spos, epos - spos);
1731 }
1732 }
1733
1734 // If a stripped CGI was the first element, remove the extra &
1735 size_t spos = 0;
1736 if ((spos = url.find("?&")) != std::string::npos)
1737 url.erase(spos + 1, 1);
1738
1739 // If stripping removed the only query parameter, remove the dangling ?
1740 if (!url.empty() && url.back() == '?')
1741 url.pop_back();
1742}

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 1744 of file XrdOucUtils.cc.

1745{
1746 std::string tmp = url.c_str();
1747 stripCgi(tmp, cgiKeys);
1748 url = tmp.c_str();
1749}
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: