Skip to content

Commit bcc0fcc

Browse files
committed
MGM: HTTP - Added opaque query to request object if access via gateway authentication
Only authz opaque is not passed. Fixes EOS-6482
1 parent 3b72f55 commit bcc0fcc

File tree

3 files changed

+89
-9
lines changed

3 files changed

+89
-9
lines changed

mgm/http/HttpServer.cc

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,12 @@ HttpServer::XrdHttpHandler(std::string& method,
400400
headers["client-real-host"] = client.host;
401401
headers["x-real-ip"] = client.host;
402402

403+
auto it = headers.find("xrd-http-fullresource");
404+
405+
if (it != headers.end()) {
406+
extractOpaqueWithoutAuthz(it->second,query);
407+
}
408+
403409
if (client.moninfo && strlen(client.moninfo)) {
404410
headers["ssl_client_s_dn"] = client.moninfo;
405411
}
@@ -469,16 +475,8 @@ HttpServer::BuildPathAndEnvOpaque
469475
return false;
470476
}
471477

472-
path = it->second;
473478
std::string opaque;
474-
size_t pos = path.find('?');
475-
476-
if ((pos != std::string::npos) && (pos != path.length())) {
477-
opaque = path.substr(pos + 1);
478-
path = path.substr(0, pos);
479-
eos::common::Path canonical_path(path);
480-
path = canonical_path.GetFullPath().c_str();
481-
}
479+
extractPathAndOpaque(it->second,path,opaque);
482480

483481
// Check if there is an explicit authorization header
484482
std::string http_authz;
@@ -526,7 +524,34 @@ HttpServer::BuildPathAndEnvOpaque
526524
return true;
527525
}
528526

527+
void HttpServer::extractPathAndOpaque(const std::string & fullpath, std::string & path, std::string & opaque)
528+
{
529+
path = fullpath;
529530

531+
size_t pos = fullpath.find('?');
532+
if ((pos != std::string::npos) && (pos != fullpath.length())) {
533+
opaque = path.substr(pos + 1);
534+
path = path.substr(0, pos);
535+
eos::common::Path canonical_path(path);
536+
path = canonical_path.GetFullPath().c_str();
537+
}
538+
539+
}
540+
541+
void HttpServer::extractOpaqueWithoutAuthz(const std::string & fullpath, std::string & opaque) {
542+
std::string path;
543+
opaque.clear();
544+
extractPathAndOpaque(fullpath,path,opaque);
545+
if(opaque.size()) {
546+
auto env_opaque = std::make_unique<XrdOucEnv>(opaque.c_str(), opaque.length());
547+
int envTidyLen;
548+
char * envTidy = env_opaque->EnvTidy(envTidyLen);
549+
if(envTidyLen > 1) {
550+
// Seen during unit tests, EnvTidy puts an ampersand at the beginning of the resulting string
551+
opaque.assign(envTidy + 1, envTidyLen - 1);
552+
}
553+
}
554+
}
530555

531556
//------------------------------------------------------------------------------
532557
// Handle clientDN specified using RFC2253 (and RFC4514) where the

mgm/http/HttpServer.hh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,24 @@ public:
165165
BuildPathAndEnvOpaque(const std::map<std::string, std::string>&
166166
normalized_headers, std::string& path,
167167
std::unique_ptr<XrdOucEnv>& env_opaque);
168+
169+
//----------------------------------------------------------------------------
170+
//! Extract opaque query from the full path passed in parameter
171+
//!
172+
//! @param fullpath the path from which we extract the opaque infos
173+
//! @param path, the extracted path
174+
//! @param opaque, the extracted opaque without the '?'
175+
//----------------------------------------------------------------------------
176+
static void extractPathAndOpaque(const std::string & fullpath, std::string & path, std::string & opaque);
177+
178+
//----------------------------------------------------------------------------
179+
//! Extract opaque query from the full path passed in parameter and remove everything
180+
//! related to authz
181+
//!
182+
//! @param fullpath the path from which we extract the opaque infos
183+
//! @param opaque, the extracted opaque without the '?' and without authz opaque query
184+
//----------------------------------------------------------------------------
185+
static void extractOpaqueWithoutAuthz(const std::string & fullpath, std::string & opaque);
168186
};
169187

170188
EOSMGMNAMESPACE_END

unit_tests/mgm/http/HttpServerTests.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,40 @@ TEST(HttpServer, ParsePathAndToken)
8282
ASSERT_TRUE(HttpServer::BuildPathAndEnvOpaque(norm_hdrs, path, env_opaque));
8383
ASSERT_STREQ("http/wizz", env_opaque->Get("eos.app"));
8484
}
85+
86+
static std::map<std::string,std::pair<std::string,std::string>> fullPathToPathAndOpaque = {
87+
{"",{"",""}},
88+
{"/eos/file.dat",{"/eos/file.dat",""}},
89+
{"/eos/file.dat?",{"/eos/file.dat",""}},
90+
{"/eos/file.dat?testopaque=1",{"/eos/file.dat","testopaque=1"}},
91+
{"/eos/file.dat?testopaque=1&authz=qwerty&test=2",{"/eos/file.dat","testopaque=1&authz=qwerty&test=2"}},
92+
};
93+
94+
TEST(HttpServer, ExtractPathAndOpaque) {
95+
for(const auto & [fullpath, pathAndOpaquePair]: fullPathToPathAndOpaque) {
96+
std::string extractedPath;
97+
std::string extractedOpaque;
98+
eos::mgm::HttpServer::extractPathAndOpaque(fullpath,extractedPath, extractedOpaque);
99+
ASSERT_EQ(pathAndOpaquePair.first,extractedPath);
100+
ASSERT_EQ(pathAndOpaquePair.second,extractedOpaque);
101+
}
102+
}
103+
104+
static std::map<std::string,std::string> fullPathToOpaque = {
105+
{"",""},
106+
{"/eos/lhcb/test/?eos.ruid=0","eos.ruid=0"},
107+
{"/eos/lhcb/",""},
108+
{"/eos/file.dat?",""},
109+
{"/eos/lhcb/passwd.txt?eos.test=0&oss.test=18&test=3","eos.test=0&oss.test=18&test=3"},
110+
{"/eos/lhcb/passwd.txt?authz=azerty&eos.test=0&oss.test=18&test=3","eos.test=0&oss.test=18&test=3"},
111+
{"/eos/lhcb/passwd.txt?eos.test=0&oss.test=18&authz=azerty&test=3","eos.test=0&oss.test=18&test=3"},
112+
{"/eos/lhcb/passwd.txt?eos.test=0&oss.test=18&test=3&authz=azerty","eos.test=0&oss.test=18&test=3"}
113+
};
114+
115+
TEST(HttpServer, ExtractOpaqueWithoutAuthz) {
116+
for (const auto & [fullpath,opaque]: fullPathToOpaque) {
117+
std::string extractedOpaque;
118+
eos::mgm::HttpServer::extractOpaqueWithoutAuthz(fullpath,extractedOpaque);
119+
ASSERT_EQ(opaque,extractedOpaque);
120+
}
121+
}

0 commit comments

Comments
 (0)