Loading...
Searching...
No Matches
XrdPssUrlInfo.cc
Go to the documentation of this file.
/******************************************************************************/
/* */
/* X r d P s s U r l I n f o . c c */
/* */
/* (c) 2018 by the Board of Trustees of the Leland Stanford, Jr., University */
/* All Rights Reserved */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include <iostream>
#include <cstring>
#include "XrdOuc/XrdOucEnv.hh"
#include "XrdOuc/XrdOucSid.hh"
#include "XrdOuc/XrdOucTPC.hh"
#include "XrdPss/XrdPssUrlInfo.hh"
#include "XrdPss/XrdPssUtils.hh"
#include "XrdSec/XrdSecEntity.hh"
/******************************************************************************/
/* S t a t i c M e m b e r s */
/******************************************************************************/
bool XrdPssUrlInfo::MapID = false;
/******************************************************************************/
/* c o p y C G I */
/******************************************************************************/
namespace
{
int copyCGI(const char *cgi, char *Buff, int Blen)
{
int n;
if (!cgi) {*Buff = 0; return 0;}
// Skip over initial ampersands
//
while(*cgi == '&' && *cgi) cgi++;
// Check if there is anything here
//
if (*cgi == 0) {*Buff = 0; return 0;}
// Copy out all variables omitting the ones that cause trouble
//
char *bP = Buff;
const char *beg = cgi;
do {if (!strncmp(cgi, "xrd.", 4) || !strncmp(cgi, "xrdcl.", 6))
{int n = cgi - beg - 1;
if (n > 0)
{if (n >= Blen) {*bP = 0; return bP - Buff;}
strncpy(bP, beg, n);
bP += n; Blen -= n; *bP = 0;
}
if ((beg = index(cgi, '&')))
{cgi = beg+1;
if (bP == Buff) beg++;
}
} else {
if ((cgi = index(cgi, '&'))) cgi++;
}
} while(beg && cgi);
// See if we have the end to copy
//
if (beg)
{n = strlen(beg) + 1;
if (n < Blen)
{strncpy(bP, beg, Blen);
bP += n;
}
}
// Return length make sure buffer ends with a null
//
*bP = 0;
//std::cerr <<"PSS cgi OT: '" <<Buff <<"' " <<(bP-Buff) <<'\n' <<std::flush;
return bP - Buff;
}
}
/******************************************************************************/
/* C o n s t r u c t o r */
/******************************************************************************/
XrdPssUrlInfo::XrdPssUrlInfo(XrdOucEnv *envP, const char *path,
const char *xtra, bool addusrcgi, bool addident)
: Path(path), CgiUsr(""), CgiUsz(0), CgiSsz(0), sidP(0),
eIDvalid(false)
{
const char *amp1= "", *amp2 = "";
// Preset for no id in the url
//
*theID = 0;
tident = 0;
// If there is an environment point, get user's cgi and set the tident from it
//
if (envP)
{if (addusrcgi && !(CgiUsr = envP->Env(CgiUsz))) CgiUsr = "";
const XrdSecEntity *secP = envP->secEnv();
if (secP)
{entityID = secP->ueid;
eIDvalid = true;
tident = secP->tident;
}
}
// Make sure we have a tident
//
if (!tident) tident = "unk.0:0@host";
// Generate additional cgi information as needed
//
if (*xtra && *xtra != '&') amp2 = "&";
if (CgiUsz) amp1 = "&";
if (addident)
{CgiSsz = snprintf(CgiSfx, sizeof(CgiSfx),
"%spss.tid=%s%s%s", amp1, tident, amp2, xtra);
} else {
if (*xtra) CgiSsz = snprintf(CgiSfx, sizeof(CgiSfx), "%s%s", amp1, xtra);
else *CgiSfx = 0;
}
}
/******************************************************************************/
/* a d d C G I */
/******************************************************************************/
bool XrdPssUrlInfo::addCGI(const char *prot, char *buff, int blen)
{
bool forXrd = XrdPssUtils::is4Xrootd(prot);
// Short circuit all of this if there is no cgi
//
if (!CgiUsz && (!CgiSsz || forXrd))
{*buff = 0;
return true;
}
// Make sure that we can fit whatever CGI we have into the buffer. Include the
// implicit question mark and ending null byte.
//
int n = CgiUsz + (forXrd ? CgiSsz : 0) + 1;
if (n >= blen) return false;
*buff++ = '?'; blen--;
// If the protocol is headed to an xroot server then we need to remove any
// offending CGI elements from the user CGI. Otherwise, we can use the CGI
// that was specified by the client.
//
if (CgiUsz)
{if (forXrd) n = copyCGI(CgiUsr, buff, blen);
else {n = CgiUsz;
strcpy(buff, CgiUsr);
}
buff += n; blen -= n;
}
// If this is destined to an xroot server, add any extended CGI.
//
if (forXrd && CgiSsz)
{if (CgiSsz >= blen) return false;
strcpy(buff, CgiSfx);
} else *buff = 0;
// All done
//
//std::cerr <<"Final URL: '" <<prot <<"' " <<strlen(prot) <<'\n' <<std::flush;
return true;
}
/******************************************************************************/
/* E x t e n d */
/******************************************************************************/
bool XrdPssUrlInfo::Extend(const char *cgi, int cgiln)
{
const char *amp = (*cgi == '&' ? "" : "&");
int blen = sizeof(CgiSfx) - CgiSsz;
if (blen <= cgiln) return false;
int n = snprintf(&CgiSfx[CgiSsz], blen, "%s%s", amp, cgi);
if (n >= blen) return false;
CgiSsz += n;
return true;
}
/******************************************************************************/
/* s e t I D */
/******************************************************************************/
void XrdPssUrlInfo::setID(const char *tid)
{
const char *atP, *colon;
// If we are mapping id then use the entity's idenification
//
if (MapID && eIDvalid)
{const char *fmt = (entityID & 0xf0000000 ? "%x@" : "U%x@");
snprintf(theID, sizeof(theID), fmt, entityID); // 8+1+nul = 10 bytes
return;
}
// Use the connection file descriptor number as the id lgnid.pid:fd@host
//
if (tid == 0) tid = tident;
if ((colon = index(tid, ':')) && (atP = index(colon+1, '@')))
{int n = atP - colon;
if (n <= (int)sizeof(theID))
{*theID = 'u';
strncpy(theID+1, colon+1, n); // Include '@'
theID[n+1] = 0;
} else *theID = 0;
} else *theID = 0;
}
XrdOucEnv.hh
XrdOucSid.hh
XrdOucTPC.hh
XrdPssUrlInfo.hh
XrdPssUtils.hh
XrdSecEntity.hh
XrdOucEnv
Definition XrdOucEnv.hh:42
XrdOucEnv::Env
char * Env(int &envlen)
Definition XrdOucEnv.hh:48
XrdOucEnv::secEnv
const XrdSecEntity * secEnv() const
Definition XrdOucEnv.hh:107
XrdPssUrlInfo::XrdPssUrlInfo
XrdPssUrlInfo(XrdOucEnv *envP, const char *path, const char *xtra="", bool addusrcgi=true, bool addident=true)
Definition XrdPssUrlInfo.cc:109
XrdPssUrlInfo::Extend
bool Extend(const char *cgi, int cgiln)
Definition XrdPssUrlInfo.cc:202
XrdPssUrlInfo::setID
void setID(const char *tid=0)
Definition XrdPssUrlInfo.cc:218
XrdPssUrlInfo::addCGI
bool addCGI(const char *prot, char *buff, int blen)
Definition XrdPssUrlInfo.cc:155
XrdPssUtils::is4Xrootd
static bool is4Xrootd(const char *pname)
Definition XrdPssUtils.cc:68
XrdSecEntity
Definition XrdSecEntity.hh:65
XrdSecEntity::tident
const char * tident
Trace identifier always preset.
Definition XrdSecEntity.hh:81
XrdSecEntity::ueid
unsigned int ueid
Unique ID of entity instance.
Definition XrdSecEntity.hh:79