XRootD
XrdCksConfig.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d C k s C o n f i g . c c */
4 /* */
5 /* (c) 2011 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <cerrno>
32 #include <cstring>
33 #include <cstdio>
34 #include <unistd.h>
35 #include <sys/param.h>
36 #include <sys/types.h>
37 
38 #include "XrdVersion.hh"
39 
40 #include "XrdCks/XrdCks.hh"
41 #include "XrdCks/XrdCksData.hh"
42 #include "XrdCks/XrdCksConfig.hh"
43 #include "XrdCks/XrdCksManager.hh"
44 #include "XrdCks/XrdCksManOss.hh"
45 #include "XrdCks/XrdCksWrapper.hh"
47 #include "XrdOuc/XrdOucStream.hh"
48 #include "XrdOuc/XrdOucUtils.hh"
49 #include "XrdSys/XrdSysError.hh"
50 #include "XrdSys/XrdSysPlatform.hh"
51 #include "XrdSys/XrdSysPlugin.hh"
52 
53 /******************************************************************************/
54 /* C o n s t r u c t o r */
55 /******************************************************************************/
56 
57 XrdCksConfig::XrdCksConfig(const char *cFN, XrdSysError *Eroute, int &aOK,
58  XrdVersionInfo &vInfo)
59  : eDest(Eroute), cfgFN(cFN), CksLib(0), CksParm(0),
60  CksList(0), CksLast(0), LibList(0), LibLast(0),
61  myVersion(vInfo), CKSopts(0)
62 {
63  static XrdVERSIONINFODEF(myVer, XrdCks, XrdVNUMBER, XrdVERSION);
64 
65 // Verify caller's version against ours
66 //
67  if (vInfo.vNum <= 0 || vInfo.vNum == myVer.vNum
68  || XrdSysPlugin::VerCmp(vInfo, myVer)) aOK = 1;
69  else aOK = 0;
70 }
71 
72 /******************************************************************************/
73 /* a d d C k s */
74 /******************************************************************************/
75 
76 XrdCks *XrdCksConfig::addCks(XrdCks *pCks, XrdOucEnv *envP)
77 {
78  XrdOucPinLoader *myLib;
79  XrdCks *(*ep)(XRDCKSADD2PARMS);
80  const char *theParm;
81  XrdOucTList *tP = LibList;
82 
83 // Create a plugin object (we will throw this away without deletion because
84 // the library must stay open but we never want to reference it again).
85 //
86  while(tP)
87  {if (!(myLib = new XrdOucPinLoader(eDest,&myVersion,"ckslib",tP->text)))
88  return 0;
89 
90  // Now get the entry point of the object creator
91  //
92  ep = (XrdCks *(*)(XRDCKSADD2PARMS))(myLib->Resolve("XrdCksAdd2"));
93  if (!ep) {myLib->Unload(true); return 0;}
94 
95  // Get the Object now
96  //
97  delete myLib;
98  theParm = (tP->val ? (tP->text) + tP->val : 0);
99  pCks = ep(*pCks, eDest, cfgFN, theParm, envP);
100  if (!pCks) return 0;
101 
102  // Move on to the next stacked plugin
103  //
104  tP = tP->next;
105  }
106 
107 // All done
108 //
109  return pCks;
110 }
111 
112 /******************************************************************************/
113 /* C o n f i g u r e */
114 /******************************************************************************/
115 
116 XrdCks *XrdCksConfig::Configure(const char *dfltCalc, int rdsz,
118 {
119  XrdCks *myCks = getCks(ossP, rdsz);
120  XrdOucTList *tP = CksList;
121  int NoGo = 0;
122 
123 // Check if we have a cks object
124 //
125  if (!myCks) return 0;
126 
127 // Stack all pugins
128 //
129  myCks = addCks(myCks, envP);
130  if (!myCks) return 0;
131 
132 // Configure the object
133 //
134  while(tP) {NoGo |= myCks->Config("ckslib", tP->text); tP = tP->next;}
135 
136 // Configure if all went well
137 //
138  if (!NoGo) NoGo = !myCks->Init(cfgFN, dfltCalc);
139 
140 // All done
141 //
142  if (NoGo) {delete myCks; myCks = 0;}
143  return myCks;
144 }
145 
146 /******************************************************************************/
147 /* Private: g e t C k s */
148 /******************************************************************************/
149 
150 XrdCks *XrdCksConfig::getCks(XrdOss *ossP, int rdsz)
151 {
152  XrdOucPinLoader *myLib;
153  XrdCks *(*ep)(XRDCKSINITPARMS);
154 
155 // Cks manager comes from the library or we use the default
156 //
157  if (!CksLib)
158  {XrdCksManager* manP;
159  if (ossP) manP = new XrdCksManOss (ossP,eDest,rdsz,myVersion);
160  else manP = new XrdCksManager( eDest,rdsz,myVersion);
161  manP->SetOpts(CKSopts);
162  return manP;
163  }
164 
165 // Create a plugin object (we will throw this away without deletion because
166 // the library must stay open but we never want to reference it again).
167 //
168  if (!(myLib = new XrdOucPinLoader(eDest, &myVersion, "ckslib", CksLib)))
169  return 0;
170 
171 // Now get the entry point of the object creator
172 //
173  ep = (XrdCks *(*)(XRDCKSINITPARMS))(myLib->Resolve("XrdCksInit"));
174  if (!ep) {myLib->Unload(true); return 0;}
175 
176 // Get the Object now
177 //
178  delete myLib;
179  return ep(eDest, cfgFN, CksParm);
180 }
181 
182 /******************************************************************************/
183 /* M a n a g e r */
184 /******************************************************************************/
185 
186 /* Function: Manager
187 
188  Purpose: Reset the manager plugin library path and parameters.
189 
190  <path> path to the library.
191  <parms> optional parms to be passed
192 
193  Output: 0 upon success or !0 upon failure.
194 */
195 
196 int XrdCksConfig::Manager(const char *Path, const char *Parms)
197 {
198 // Replace the library path and parameters. Note that for default plugins
199 // we reset the path to null to indicate we want the default plugin.
200 //
201  if (CksLib) free(CksLib);
202  CksLib = (Path ? strdup(Path) : 0);
203  if (CksParm) free(CksParm);
204  CksParm = (Parms && *Parms ? strdup(Parms) : 0);
205  return 0;
206 }
207 
208 /******************************************************************************/
209 /* P a r s e L i b */
210 /******************************************************************************/
211 
212 /* Function: ParseLib
213 
214  Purpose: To parse the directive: ckslib <digest> <path> [<parms>]
215 
216  <digest> the name of the checksum. The special name "*" is used
217  load the checksum manager library.
218  <path> the path of the checksum library to be used.
219  <parms> optional parms to be passed
220 
221  Output: 0 upon success or !0 upon failure.
222 */
223 
225 {
226  static const int nameSize = XrdCksData::NameSize;
227  static const int pathSize = MAXPATHLEN;
228  static const int parmSize = 1024;
229  XrdOucTList *tP;
230  char *val, buff[nameSize + pathSize + parmSize + 8], parms[parmSize], *bP;
231  int n;
232 
233 // Get the digest
234 //
235  if (!(val = Config.GetWord()) || !val[0])
236  {eDest->Emsg("Config", "ckslib digest not specified"); return 1;}
237  n = strlen(val);
238  if (n >= nameSize)
239  {eDest->Emsg("Config", "ckslib digest name too long -", val); return 1;}
240  strcpy(buff, val); XrdOucUtils::toLower(buff); bP = buff+n; *bP++ = ' ';
241 
242 // Determine the library type
243 //
244  if (!strcmp(val, "*")) libType = -1;
245  else if (!strcmp(val, "=")) libType = 1;
246  else libType = 0;
247 
248 // Get the path
249 //
250  if (!(val = Config.GetWord()) || !val[0])
251  {eDest->Emsg("Config", "ckslib path not specified for", buff); return 1;}
252  n = strlen(val);
253  if (n > pathSize)
254  {eDest->Emsg("Config", "ckslib path name too long -", val); return 1;}
255  strcpy(bP, val); bP += n;
256 
257 // Check if path is 'default' and is appropriate for this context
258 //
259  if (!strcmp("default", val))
260  {if (!libType)
261  {eDest->Emsg("Config","ckslib 'default' is only valid for '*' and '='");
262  return 1;
263  }
264  if (!ParseOpt(Config)) return 1;
265  return Manager(0,0);
266  }
267 
268 // Record any parms
269 //
270  *parms = 0;
271  if (!Config.GetRest(parms, parmSize))
272  {eDest->Emsg("Config", "ckslib parameters too long for", buff); return 1;}
273 
274 // Check if this is for the manager
275 //
276  if (libType) return Manager(buff+2, parms);
277 
278 // Create a new TList object either for a digest or stackable library
279 //
280  n = (strncmp(buff, "++ ", 3) ? 0 : 3);
281  *bP = ' '; strcpy(bP+1, parms);
282  tP = new XrdOucTList(buff + n);
283 
284 // Add this digest to the list of digests or stackable library list
285 //
286  if (n)
287  {n = (bP - buff) - n;
288  tP->text[n] = 0;
289  tP->val = (*parms ? n+1 : 0);
290  if (LibLast) LibLast->next = tP;
291  else LibList = tP;
292  LibLast = tP;
293  } else {
294  if (CksLast) CksLast->next = tP;
295  else CksList = tP;
296  CksLast = tP;
297  }
298  return 0;
299 }
300 
301 /******************************************************************************/
302 /* P a r s e O p t */
303 /******************************************************************************/
304 
305 /* Function: ParseOpt
306 
307  Purpose: To parse the paramneters for the default manager plugin
308 
309 
310  Output: true upon success or false upon failure.
311 */
312 
314 {
315  char* val = Config.GetWord();
316 
317 // Get the next word, if any
318 //
319  while(val)
320  {if (!strcmp(val, "nomtchk")) CKSopts |= XrdCksManager::Cks_nomtchk;
321  else break;
322  val = Config.GetWord();
323  }
324 
325 // Check for errors
326 //
327  if (val)
328  {eDest->Emsg("Config", "Invalid default ckslib plugin parameter -", val);
329  return false;
330  }
331  return true;
332 }
#define XRDCKSADD2PARMS
#define XRDCKSINITPARMS
Definition: XrdCks.hh:296
static XrdSysError eDest(0,"crypto_")
XrdOucString Path
XrdCks * Configure(const char *dfltCalc=0, int rdsz=0, XrdOss *ossP=0, XrdOucEnv *envP=0)
XrdCksConfig(const char *cFN, XrdSysError *Eroute, int &aOK, XrdVersionInfo &vInfo)
Definition: XrdCksConfig.cc:57
bool ParseOpt(XrdOucStream &Config)
int ParseLib(XrdOucStream &Config, int &libType)
static const int NameSize
Definition: XrdCksData.hh:41
void SetOpts(int opt)
Definition: XrdCks.hh:92
virtual int Init(const char *ConfigFN, const char *DfltCalc=0)=0
virtual int Config(const char *Token, char *Line)=0
void * Resolve(const char *symbl, int mcnt=1)
void Unload(bool dodel=false)
XrdOucTList * next
Definition: XrdOucTList.hh:45
char * text
Definition: XrdOucTList.hh:46
static void toLower(char *str)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
static bool VerCmp(XrdVersionInfo &vInf1, XrdVersionInfo &vInf2, bool noMsg=false)
XrdVersionInfo myVersion
XrdVERSIONINFODEF(myVersion, cmsclient, XrdVNUMBER, XrdVERSION)
XrdCmsConfig Config
XrdOucEnv * envP
Definition: XrdPss.cc:109