XRootD
Loading...
Searching...
No Matches
XrdSecProtector.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d S e c P r o t e c t o r . c c */
4/* */
5/* (c) 2016 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* Produced by Andrew Hanushevsky for Stanford University under contract */
7/* DE-AC02-76-SFO0515 with the Department of Energy */
8/* */
9/* This file is part of the XRootD software suite. */
10/* */
11/* XRootD is free software: you can redistribute it and/or modify it under */
12/* the terms of the GNU Lesser General Public License as published by the */
13/* Free Software Foundation, either version 3 of the License, or (at your */
14/* option) any later version. */
15/* */
16/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19/* License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24/* */
25/* The copyright holder's institutional names and contributor's names may not */
26/* be used to endorse or promote products derived from this software without */
27/* specific prior written permission of the institution or contributor. */
28/******************************************************************************/
29
30#include <cerrno>
31#include <cinttypes>
32#include <cstring>
33#include <sys/types.h>
34
35#include "XrdVersion.hh"
36
37#include "XrdNet/XrdNetIF.hh"
41#include "XrdSys/XrdSysError.hh"
42
43/******************************************************************************/
44/* L i b r a r y L i n k a g e */
45/******************************************************************************/
46
47namespace
48{
49class protoProtector : public XrdSecProtector
50{
51public:
52 protoProtector() {}
53 ~protoProtector() {}
54};
55
56protoProtector baseProtector;
57}
58
60
62
63/******************************************************************************/
64/* S e r v e r - S i d e C o n f i g u r a t i o n */
65/******************************************************************************/
66
67namespace
68{
69struct ProtInfo {XrdSecProtect *theProt;
71 bool relaxed;
72 bool force;
73 ProtInfo() : theProt(0), relaxed(false), force(false)
74 {reqs.theTag = 'S';
75 reqs.rsvd = 0;
76 reqs.secver = kXR_secver_0;
77 reqs.secopt = 0;
78 reqs.seclvl = kXR_secNone;
79 reqs.secvsz = 0;
80 }
81 } lrTab[XrdSecProtector::isLR];
82
83bool lrSame = true;
84bool noProt = true;
85}
86
87/******************************************************************************/
88/* S e r v e r - S i d e E r r o r M e s s a g e R o u t i n g */
89/******************************************************************************/
90
91namespace
92{
93XrdSysError Say(0, "sec_");
94}
95
96/******************************************************************************/
97/* C o n f i g */
98/******************************************************************************/
99
101 const XrdSecProtectParms &rmtParms,
102 XrdSysLogger &logr)
103{
104
105// Set the logger right off
106//
107 Say.logger(&logr);
108
109// Setup local protection
110//
111 if (lclParms.level != XrdSecProtectParms::secNone)
112 {Config(lclParms, lrTab[isLcl].reqs);
113 lrTab[isLcl].theProt = new XrdSecProtect;
114 lrTab[isLcl].theProt->SetProtection(lrTab[isLcl].reqs);
115 }
116
117// Setup remote protection (check for reuse of local protection)
118//
119 if (rmtParms.level == lclParms.level)
120 {lrTab[isRmt] = lrTab[isLcl];
121 lrSame = true;
122 } else {
123 lrSame = false;
124 if (rmtParms.level != XrdSecProtectParms::secNone)
125 {Config(rmtParms, lrTab[isRmt].reqs);
126 lrTab[isRmt].theProt = new XrdSecProtect;
127 lrTab[isRmt].theProt->SetProtection(lrTab[isRmt].reqs);
128 }
129 }
130
131// Record relax flags
132//
133 lrTab[isLcl].relaxed = (lclParms.opts & XrdSecProtectParms::relax) != 0;
134 lrTab[isLcl].force = (lclParms.opts & XrdSecProtectParms::force) != 0;
135 lrTab[isRmt].relaxed = (rmtParms.opts & XrdSecProtectParms::relax) != 0;
136 lrTab[isRmt].force = (rmtParms.opts & XrdSecProtectParms::force) != 0;
137
138// Setup shortcut flag
139//
140 noProt = (lrTab[isLcl].theProt == 0) && (lrTab[isRmt].theProt == 0);
141
142// All done
143//
144 return true;
145}
146
147/******************************************************************************/
148
151{
152 unsigned int lvl;
153
154// Setup options
155//
156 if ((parms.opts & XrdSecProtectParms::doData) != 0)
157 reqs.secopt |= kXR_secOData;
158 if ((parms.opts & XrdSecProtectParms::force) != 0)
159 reqs.secopt |= kXR_secOFrce;
160
161// Setup level
162//
163 switch(parms.level)
165 break;
167 break;
169 break;
171 break;
172 default: lvl = kXR_secNone;
173 break;
174 }
175 reqs.seclvl = lvl;
176}
177
178/******************************************************************************/
179/* L N a m e */
180/******************************************************************************/
181
183{
184 static const char *lvlVec[] = {"none", "compatible", "standard",
185 "intense", "pedantic"};
186
187// Validate the level
188//
190 else if (level > XrdSecProtectParms::secPedantic)
192
193// Return the level name
194//
195 return lvlVec[level];
196}
197
198/******************************************************************************/
199/* N e w 4 C l i e n t */
200/******************************************************************************/
201
203 const ServerResponseReqs_Protocol &inReqs,
204 unsigned int reqLen)
205{
206 static const unsigned int hdrLen = sizeof(ServerResponseBody_Protocol)
208 XrdSecProtect *secP;
209 unsigned int vLen = static_cast<unsigned int>(inReqs.secvsz)
211 bool okED;
212
213// Validate the incoming struct (if it's bad skip the security) and that any
214// security is actually wanted.
215//
216 if (vLen+hdrLen > reqLen
217 || (inReqs.secvsz == 0 && inReqs.seclvl == kXR_secNone)) return 0;
218
219// If the auth protocol doesn't support encryption, see if we still need to
220// send off signed requests (mostly for testng)
221//
222 okED = aprot.getKey() > 0;
223 if (!okED && (inReqs.secopt & kXR_secOFrce) == 0) return 0;
224
225// Get a new security object and set its security level
226//
227 secP = new XrdSecProtect(&aprot, okED);
228 secP->SetProtection(inReqs);
229
230// All done
231//
232 return secP;
233}
234
235/******************************************************************************/
236/* N e w 4 S e r v e r */
237/******************************************************************************/
238
240{
241 static const char *wFrc = "authentication can't encrypt; "
242 "continuing without it!";
243 static const char *wIgn = "authentication can't encrypt; "
244 "allowing unsigned requests!";
245 XrdSecProtect *secP;
246 lrType theLR;
247 bool okED;
248
249// Check if we need any security at all
250//
251 if (noProt) return 0;
252
253// Now we need to see whether this is local or remote of if it matters
254//
255 if (lrSame) theLR = isLcl;
256 else theLR = (XrdNetIF::InDomain(aprot.Entity.addrInfo) ? isLcl : isRmt);
257
258// Now check again, as may not need any protection for the domain
259//
260 if (lrTab[theLR].theProt == 0) return 0;
261
262// Check for relaxed processing
263//
264 if (plvl < kXR_PROTSIGNVERSION && lrTab[theLR].relaxed) return 0;
265
266// Check if protocol supports encryption
267//
268 okED = aprot.getKey() > 0;
269 if (!okED)
270 {char pName[XrdSecPROTOIDSIZE+1];
271 const char *action;
272 strncpy(pName, aprot.Entity.prot, XrdSecPROTOIDSIZE);
273 pName[XrdSecPROTOIDSIZE] = 0;
274 action = (lrTab[theLR].force ? wFrc : wIgn);
275 Say.Emsg("Protect", aprot.Entity.tident, pName, action);
276 if (!lrTab[theLR].force) return 0;
277 }
278
279// Get a new security object and make it a clone of this right one
280//
281 secP = new XrdSecProtect(&aprot, *lrTab[theLR].theProt, okED);
282
283// All done
284//
285 return secP;
286}
287
288/******************************************************************************/
289/* P r o t R e s p */
290/******************************************************************************/
291
293 XrdNetAddrInfo &nai, int pver)
294{
295 static const int rsplen = sizeof(ServerResponseReqs_Protocol)
298
299// Check if we need any response at all
300//
301 if (noProt) return 0;
302
303// Get the right response
304//
305 if (lrSame || XrdNetIF::InDomain(&nai)) myResp = &lrTab[isLcl].reqs;
306 else myResp = &lrTab[isRmt].reqs;
307
308// Return result
309//
310 memcpy(&resp, myResp, rsplen);
311 return rsplen;
312}
#define kXR_secStandard
#define kXR_PROTSIGNVERSION
Definition XProtocol.hh:74
#define kXR_secOFrce
#define kXR_secNone
#define kXR_secOData
#define kXR_secPedantic
#define kXR_secver_0
#define kXR_secCompatible
#define kXR_secIntense
XrdOucPup XrdCmsParser::Pup & Say
#define XrdSecPROTOIDSIZE
XrdVERSIONINFO(XrdSecProtObjectP,"secProt")
XrdSecProtector * XrdSecProtObjectP
static bool InDomain(XrdNetAddrInfo *epaddr)
Definition XrdNetIF.cc:606
XrdNetAddrInfo * addrInfo
Entity's connection details.
const char * tident
Trace identifier always preset.
char prot[XrdSecPROTOIDSIZE]
Auth protocol used (e.g. krb5)
static const int doData
Secure data.
static const int relax
relax old clients
secLevel level
In: The desired level.
static const int force
Allow unencryted hash.
int opts
In: Options:
void SetProtection(const ServerResponseReqs_Protocol &inReqs)
virtual XrdSecProtect * New4Client(XrdSecProtocol &aprot, const ServerResponseReqs_Protocol &inReqs, unsigned int reqLen)
virtual XrdSecProtect * New4Server(XrdSecProtocol &aprot, int plvl)
virtual int ProtResp(ServerResponseReqs_Protocol &resp, XrdNetAddrInfo &nai, int pver)
virtual bool Config(const XrdSecProtectParms &lclParms, const XrdSecProtectParms &rmtParms, XrdSysLogger &logr)
virtual const char * LName(XrdSecProtectParms::secLevel level)
XrdSecEntity Entity
virtual int getKey(char *buff=0, int size=0)