00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 const char *XrdCmsSecurityCVSID = "$Id: XrdCmsSecurity.cc 35287 2010-09-14 21:19:35Z ganis $";
00014
00015
00016
00017 #ifdef __solaris__
00018 #include <sys/isa_defs.h>
00019 #if defined(_ILP32) && (_FILE_OFFSET_BITS != 32)
00020 #undef _FILE_OFFSET_BITS
00021 #define _FILE_OFFSET_BITS 32
00022 #undef _LARGEFILE_SOURCE
00023 #endif
00024 #endif
00025
00026 #include <dlfcn.h>
00027 #ifndef __macos__
00028 #include <link.h>
00029 #endif
00030
00031 #include <stdlib.h>
00032
00033 #include "XProtocol/YProtocol.hh"
00034
00035 #include "Xrd/XrdLink.hh"
00036
00037 #include "XrdCms/XrdCmsSecurity.hh"
00038 #include "XrdCms/XrdCmsTalk.hh"
00039 #include "XrdCms/XrdCmsTrace.hh"
00040
00041 #include "XrdOuc/XrdOucEnv.hh"
00042 #include "XrdOuc/XrdOucErrInfo.hh"
00043 #include "XrdOuc/XrdOucTList.hh"
00044 #include "XrdSys/XrdSysError.hh"
00045 #include "XrdSys/XrdSysPthread.hh"
00046
00047 using namespace XrdCms;
00048
00049
00050
00051
00052
00053 extern XrdSecProtocol *(*XrdXrootdSecGetProtocol)
00054 (const char *hostname,
00055 const struct sockaddr &netaddr,
00056 const XrdSecParameters &parms,
00057 XrdOucErrInfo *einfo);
00058
00059
00060
00061
00062
00063 namespace XrdCms
00064 {
00065 XrdSecProtocol *(*secProtocol)
00066 (const char *hostname,
00067 const struct sockaddr &netaddr,
00068 const XrdSecParameters &parms,
00069 XrdOucErrInfo *einfo)=0;
00070 }
00071
00072 XrdSecService *XrdCmsSecurity::DHS = 0;
00073
00074
00075
00076
00077
00078 int XrdCmsSecurity::Authenticate(XrdLink *Link, const char *Token, int Toksz)
00079 {
00080 CmsRRHdr myHdr = {0, kYR_xauth, 0, 0};
00081 struct sockaddr netaddr;
00082 XrdSecCredentials cred;
00083 XrdSecProtocol *AuthProt = 0;
00084 XrdSecParameters *parm = 0;
00085 XrdOucErrInfo eMsg;
00086 const char *eText = 0;
00087 char *authName, authBuff[4096];
00088 int rc, myDlen, abLen = sizeof(authBuff);
00089
00090
00091
00092 if ((eText = XrdCmsTalk::Request(Link, myHdr, (char *)Token, Toksz+1)))
00093 {Say.Emsg("Auth",Link->Host(),"authentication failed;",eText);
00094 return 0;
00095 }
00096
00097
00098
00099 do {
00100
00101
00102
00103 if ((eText = XrdCmsTalk::Attend(Link,myHdr,authBuff,abLen,myDlen))) break;
00104 if (myHdr.rrCode != kYR_xauth) {eText = "invalid auth response"; break;}
00105 cred.size = myDlen; cred.buffer = authBuff;
00106
00107
00108
00109 if (!AuthProt)
00110 {const char *hname = Link->Name(&netaddr);
00111 if (!DHS
00112 || !(AuthProt=DHS->getProtocol((char *)hname,netaddr,&cred,&eMsg)))
00113 {eText = eMsg.getErrText(rc); break;}
00114 }
00115
00116
00117
00118 if (!(rc = AuthProt->Authenticate(&cred, &parm, &eMsg))) break;
00119 if (rc < 0) {eText = eMsg.getErrText(rc); break;}
00120 if (parm)
00121 {eText = XrdCmsTalk::Request(Link, myHdr, parm->buffer, parm->size);
00122 delete parm;
00123 if (eText) break;
00124 } else {eText = "auth interface violation"; break;}
00125
00126 } while(1);
00127
00128
00129
00130 if (!eText)
00131 {if (!(authName = AuthProt->Entity.name)) eText = "entity name missing";
00132 else {Link->setID(authName,0);
00133 Say.Emsg("Auth",Link->Host(),"authenticated as", authName);
00134 }
00135 }
00136
00137
00138
00139 if (eText) Say.Emsg("Auth",Link->Host(),"authentication failed;",eText);
00140
00141
00142
00143 if (AuthProt) AuthProt->Delete();
00144 return (eText == 0);
00145 }
00146
00147
00148
00149
00150
00151 int XrdCmsSecurity::Configure(const char *Lib, const char *Cfn)
00152 {
00153 static XrdSysMutex myMutex;
00154 XrdSysMutexHelper hlpMtx(&myMutex);
00155 XrdSecService *(*ep)(XrdSysLogger *, const char *cfn);
00156 static void *libhandle = 0;
00157
00158
00159
00160 if (!Cfn)
00161 {if (secProtocol) return 1;
00162 else if (XrdXrootdSecGetProtocol)
00163 {secProtocol = XrdXrootdSecGetProtocol; return 1;}
00164 }
00165
00166
00167
00168 if (!libhandle && !(libhandle = dlopen(Lib, RTLD_NOW)))
00169 {Say.Emsg("Config",dlerror(),"opening shared library",Lib);
00170 return 0;
00171 }
00172
00173
00174
00175 if (! secProtocol
00176 && !(secProtocol = (XrdSecProtocol *(*)(const char *,
00177 const struct sockaddr &,
00178 const XrdSecParameters &,
00179 XrdOucErrInfo *))
00180 dlsym(libhandle, "XrdSecGetProtocol")))
00181 {Say.Emsg("Config",dlerror(),"finding XrdSecGetProtocol() in",Lib);
00182 return 0;
00183 }
00184
00185
00186
00187 if (!Cfn || DHS) return 1;
00188
00189
00190
00191 if (!(ep = (XrdSecService *(*)(XrdSysLogger *, const char *cfn))dlsym(libhandle,
00192 "XrdSecgetService")))
00193 {Say.Emsg("Config",dlerror(),"finding XrdSecgetService() in",Lib);
00194 return 0;
00195 }
00196
00197
00198
00199 if (!(DHS = (*ep)(Say.logger(), Cfn)))
00200 {Say.Emsg("Config","Unable to create security service object via",Lib);
00201 return 0;
00202 }
00203
00204
00205
00206 return 1;
00207 }
00208
00209
00210
00211
00212
00213 const char *XrdCmsSecurity::getToken(int &size, const char *hostname)
00214 {
00215
00216
00217
00218 if (!DHS) {size = 0; return 0;}
00219
00220
00221
00222 return DHS->getParms(size, hostname);
00223 }
00224
00225
00226
00227
00228
00229 int XrdCmsSecurity::Identify(XrdLink *Link, XrdCms::CmsRRHdr &inHdr,
00230 char *authBuff, int abLen)
00231 {
00232 CmsRRHdr outHdr = {0, kYR_xauth, 0, 0};
00233 struct sockaddr netaddr;
00234 const char *hname = Link->Host(&netaddr);
00235 XrdSecCredentials *cred;
00236 XrdSecProtocol *AuthProt = 0;
00237 XrdSecParameters AuthParm, *AuthP = 0;
00238 XrdOucErrInfo eMsg;
00239 const char *eText = 0;
00240 int rc, myDlen;
00241
00242
00243
00244 if (!secProtocol && !Configure("libXrdSec.so"))
00245 {Say.Emsg("Auth",Link->Host(),"authentication configuration failed.");
00246 return 0;
00247 }
00248
00249
00250
00251 AuthParm.buffer = (char *)authBuff; AuthParm.size = strlen(authBuff);
00252 if (!(AuthProt = secProtocol((char *)hname, netaddr, AuthParm, &eMsg)))
00253 {Say.Emsg("Auth",hname,"getProtocol() failed;",eMsg.getErrText(rc));
00254 return 0;
00255 }
00256
00257
00258
00259 do {
00260
00261
00262
00263 if (!(cred = AuthProt->getCredentials(AuthP, &eMsg)))
00264 {eText = eMsg.getErrText(rc); break;}
00265
00266
00267
00268 eText = XrdCmsTalk::Request(Link, outHdr, cred->buffer, cred->size);
00269 delete cred;
00270 if (eText) break;
00271
00272
00273
00274 if ((eText = XrdCmsTalk::Attend(Link,inHdr,authBuff,abLen,myDlen))) break;
00275 AuthParm.size = myDlen; AuthParm.buffer = authBuff; AuthP = &AuthParm;
00276
00277 } while(inHdr.rrCode == kYR_xauth);
00278
00279
00280
00281 if (eText) Say.Emsg("Auth",Link->Host(),"authentication failed;",eText);
00282
00283
00284
00285 if (AuthProt) AuthProt->Delete();
00286 return (eText == 0);
00287 }
00288
00289
00290
00291
00292
00293 char *XrdCmsSecurity::setSystemID(XrdOucTList *tp, const char *iName,
00294 const char *iHost, char iType)
00295 {
00296 XrdOucTList *tpF;
00297 char sidbuff[8192], *sidend = sidbuff+sizeof(sidbuff)-32, *sp, *cP;
00298 char *fMan, *fp, *xp;
00299 int n;
00300
00301
00302
00303 if (!iName || !*iName) iName = "anon";
00304 if (!iHost || !*iHost) iHost = "localhost";
00305 strcpy(sidbuff, iName); strcat(sidbuff, "-");
00306 sp = sidbuff + strlen(sidbuff);
00307 *sp++ = iType; *sp++ = ' '; cP = sp;
00308
00309
00310
00311 if (!tp) sp += sprintf(sp, "%s@%s", iName, iHost);
00312 else {tpF = tp;
00313 fMan = tp->text + strlen(tp->text) - 1;
00314 while((tp = tp->next))
00315 {fp = fMan; xp = tp->text + strlen(tp->text) - 1;
00316 do {if (*fp != *xp) break;
00317 xp--;
00318 } while(fp-- != tpF->text);
00319 if ((n = xp - tp->text + 1) > 0)
00320 {sp += sprintf(sp, "%d", tp->val);
00321 if (sp+n >= sidend) return (char *)0;
00322 strncpy(sp, tp->text, n); sp += n;
00323 }
00324 }
00325 sp += sprintf(sp, "%d", tpF->val);
00326 n = strlen(tpF->text);
00327 if (sp+n >= sidend) return (char *)0;
00328 strcpy(sp, tpF->text); sp += n;
00329 }
00330
00331
00332
00333 *sp = '\0';
00334 XrdOucEnv::Export("XRDCMSCLUSTERID", cP);
00335
00336
00337
00338 return strdup(sidbuff);
00339 }