XRootD
Loading...
Searching...
No Matches
XrdSecLoadSecurity.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d S e c L o a d S e c u r i t y . c c */
4/* */
5/* (c) 2014 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 <iostream>
31
32#include "XrdVersion.hh"
33
35
39#include "XrdSys/XrdSysError.hh"
42
43/******************************************************************************/
44/* G l o b a l s */
45/******************************************************************************/
46
47namespace
48{
49static XrdVERSIONINFODEF(myVersion, XrdSecLoader, XrdVNUMBER, XrdVERSION);
50
51XrdSysMutex protMutex;
52}
53
55{
57int protRC = 0;
58}
59
60/******************************************************************************/
61/* P l u g */
62/******************************************************************************/
63
64namespace
65{
66int Plug(XrdOucPinLoader *piP, XrdSecGetProt_t *getP, XrdSecGetServ_t *ep)
67{
68// If we need to load the protocol factory do so now
69//
70 if (getP && !(*getP=(XrdSecGetProt_t)piP->Resolve("XrdSecGetProtocol")))
71 return 1;
72
73// If we do not need to load the security service we are done
74//
75 if (!ep) return 0;
76
77// Load the security service creator
78//
79 if ((*ep = (XrdSecGetServ_t)piP->Resolve("XrdSecgetService"))) return 0;
80
81// We failed this is eiter soft or hard depending on what else we loaded
82//
83 return (getP ? -1 : 1);
84}
85}
86
87/******************************************************************************/
88/* Private: L o a d */
89/******************************************************************************/
90
91namespace
92{
93int Load( char *eBuff, int eBlen,
94 const char *cfn, const char *seclib,
95 XrdSecGetProt_t *getP, XrdSecService **secP=0,
97{
99 XrdOucPinLoader *piP;
100 const char *mySecLib = "libXrdSec.so";
101 int rc;
102
103// Check for default path
104//
105 if (!seclib) seclib = mySecLib;
106
107// Get a plugin loader object
108//
109 if (eDest) piP = new XrdOucPinLoader(eDest,
110 &myVersion, "seclib", seclib);
111 else piP = new XrdOucPinLoader(eBuff, eBlen,
112 &myVersion, "seclib", seclib);
113
114// Load the appropriate pointers and get required objects.
115//
116 rc = Plug(piP, getP, &ep);
117 if (rc == 0)
118 {if (secP && !(*secP = (*ep)(eDest->logger(), cfn))) rc = 1;
119 if (!rc) {delete piP; return 0;}
120 }
121
122// We failed, so bail out
123//
124 if (eDest)
125 eDest->Say("Config ","Unable to create security framework via ", seclib);
126 piP->Unload(true);
127 return 1;
128}
129}
130
131/******************************************************************************/
132
133namespace
134{
135int Load( char *eBuff, int eBlen,
136 const char *protlib, XrdSysError *eDest=0)
137{
138 XrdSecProtector **protPP;
139 XrdOucPinLoader *piP;
140 const char *myProtLib = "libXrdSecProt.so";
141
142// Check for default path
143//
144 if (!protlib) protlib = myProtLib;
145
146// Get a plugin loader object
147//
148 if (eDest) piP = new XrdOucPinLoader(eDest,
149 &myVersion, "protlib", protlib);
150 else piP = new XrdOucPinLoader(eBuff, eBlen,
151 &myVersion, "protlib", protlib);
152
153// Get the protection object which also is a factory object.
154//
155 protPP = (XrdSecProtector **)piP->Resolve("XrdSecProtObjectP");
156 if (protPP)
158 delete piP;
159 return 0;
160 }
161 return 1;
162
163// We failed, so bail out
164//
165 if (eDest)
166 eDest->Say("Config ","Unable to create protection framework via ",protlib);
167 piP->Unload(true);
168 return ENOENT;
169}
170}
171
172/******************************************************************************/
173/* X r d S e c L o a d F a c t o r y */
174/******************************************************************************/
175
176XrdSecGetProt_t XrdSecLoadSecFactory(char *eBuff, int eBlen, const char *seclib)
177{
178 XrdSecGetProt_t getP;
179 int rc;
180
181// Load required plugin nd obtain pointers
182//
183 rc = Load(eBuff, eBlen, 0, seclib, &getP);
184 if (!rc) return getP;
185
186// Issue correct error message, if any
187//
188 if (!seclib) seclib = "default";
189
190 if (rc < 0)
191 snprintf(eBuff, eBlen,
192 "Unable to create security framework via %s; invalid path.",
193 seclib);
194 else if (!(*eBuff))
195 snprintf(eBuff, eBlen,
196 "Unable to create security framework via %s", seclib);
197 return 0;
198}
199
200/******************************************************************************/
201/* X r d S e c G e t P r o t e c t i o n */
202/******************************************************************************/
203
204// This is used client-side only
205
207 XrdSecProtocol &aprot,
209 unsigned int resplen)
210{
211 static const unsigned int hdrLen = sizeof(ServerResponseReqs_Protocol) - 2;
212 static const unsigned int minLen = kXR_ShortProtRespLen + hdrLen;
213 XrdSecProtector *pObj;
214 unsigned int vLen;
215 int rc;
216
217// First validate the response before passing it to anyone
218//
219 protP = 0;
220 if (resplen <= kXR_ShortProtRespLen) return 0;
221 if (resplen < minLen) return -EINVAL;
222 vLen = static_cast<unsigned int>(resp.secreq.secvsz)
224 if (vLen + minLen > resplen) return -EINVAL;
225
226// Our first step is to see if any protection is required
227//
228 if (vLen == 0 && resp.secreq.seclvl == kXR_secNone) return 0;
229
230// The next step is to see if we have a protector object. If we do not then
231// we need to load the library that provides such objects. This needs to be
232// MT-safe as it may be called at any time by any thread.
233//
234 protMutex.Lock();
235 if (!(pObj = XrdSecProtection::theProtector))
237 {char eBuff[2048];
238 if ((XrdSecProtection::protRC = Load(eBuff, sizeof(eBuff), 0)))
239 std::cerr <<"SecLoad: " <<eBuff <<'\n' <<std::flush;
240 else
242 }
243 if ((rc = XrdSecProtection::protRC))
244 {protMutex.UnLock();
245 return -rc;
246 }
247 }
248 protMutex.UnLock();
249
250// Return new protection object
251//
252 protP = pObj->New4Client(aprot, resp.secreq, resplen-kXR_ShortProtRespLen);
253 return (protP ? 1 : 0);
254}
255
256/******************************************************************************/
257/* X r d S e c L o a d P r o t e c t i o n */
258/******************************************************************************/
259
260// This is a one-time server-side call
261
263{
264
265// Load the protection object. This is done in the main thread do no mutex
266//
267 XrdSecProtection::protRC = Load(0, 0, 0, &erP);
268
269// All done, return result
270//
272}
273
274/******************************************************************************/
275/* X r d S e c L o a d S e c S e r v i c e */
276/******************************************************************************/
277
279 const char *cfn,
280 const char *seclib,
281 XrdSecGetProt_t *getP,
282 XrdSecProtector**proP)
283{
284 XrdSecService *CIA;
285
286// Load required plugin nd obtain pointers
287//
288 if (Load(0, 0, cfn, seclib, getP, &CIA, eDest)) return 0;
289
290// Set the protectorobject. Note that the securityservice will load it if
291// is needed and we will havecaptured its pointer. This sort of a hack but
292// we can't change the SecService object as it is a public interface.
293//
294 if (proP) *proP = XrdSecProtection::theProtector;
295 return CIA;
296}
#define kXR_ShortProtRespLen
#define kXR_secNone
ServerResponseReqs_Protocol secreq
static XrdSysError eDest(0,"crypto_")
static XrdVERSIONINFODEF(compiledVer, XrdHttpProtocolTest, XrdVNUMBER, XrdVERSION)
XrdSecProtocol *(* XrdSecGetProt_t)(const char *hostname, XrdNetAddrInfo &endPoint, XrdSecParameters &sectoken, XrdOucErrInfo *einfo)
Typedef to simplify the encoding of methods returning XrdSecProtocol.
XrdSecService *(* XrdSecGetServ_t)(XrdSysLogger *, const char *)
XrdSecGetProt_t XrdSecLoadSecFactory(char *eBuff, int eBlen, const char *seclib)
XrdSecService * XrdSecLoadSecService(XrdSysError *eDest, const char *cfn, const char *seclib, XrdSecGetProt_t *getP, XrdSecProtector **proP)
XrdSecProtector * XrdSecLoadProtection(XrdSysError &erP)
int XrdSecGetProtection(XrdSecProtect *&protP, XrdSecProtocol &aprot, ServerResponseBody_Protocol &resp, unsigned int resplen)
void * Resolve(const char *symbl, int mcnt=1)
void Unload(bool dodel=false)
virtual XrdSecProtect * New4Client(XrdSecProtocol &aprot, const ServerResponseReqs_Protocol &inReqs, unsigned int reqLen)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
XrdSysLogger * logger(XrdSysLogger *lp=0)
XrdSecProtector * theProtector