XRootD
Loading...
Searching...
No Matches
XrdSecProtocolpwd Class Reference

#include <XrdSecProtocolpwd.hh>

Inheritance diagram for XrdSecProtocolpwd:
Collaboration diagram for XrdSecProtocolpwd:

Public Member Functions

 XrdSecProtocolpwd (int opts, const char *hname, XrdNetAddrInfo &endPoint, const char *parms=0)
virtual ~XrdSecProtocolpwd ()
int Authenticate (XrdSecCredentials *cred, XrdSecParameters **parms, XrdOucErrInfo *einfo=0)
void Delete ()
 Delete the protocol object. DO NOT use C++ delete() on this object.
XrdSecCredentialsgetCredentials (XrdSecParameters *parm=0, XrdOucErrInfo *einfo=0)
Public Member Functions inherited from XrdSecProtocol
 XrdSecProtocol (const char *pName)
 Constructor.
virtual int Decrypt (const char *inbuff, int inlen, XrdSecBuffer **outbuff)
virtual int Encrypt (const char *inbuff, int inlen, XrdSecBuffer **outbuff)
virtual int getKey (char *buff=0, int size=0)
virtual bool needTLS ()
 Check if this protocol requires TLS to properly function.
virtual int setKey (char *buff, int size)
virtual int Sign (const char *inbuff, int inlen, XrdSecBuffer **outbuff)
virtual int Verify (const char *inbuff, int inlen, const char *sigbuff, int siglen)

Static Public Member Functions

static XrdOucTraceEnableTracing ()
static char * Init (pwdOptions o, XrdOucErrInfo *erp)
static void PrintTimeStat ()

Additional Inherited Members

Public Attributes inherited from XrdSecProtocol
XrdSecEntity Entity
Protected Member Functions inherited from XrdSecProtocol
virtual ~XrdSecProtocol ()
 Destructor (prevents use of direct delete).

Detailed Description

Definition at line 285 of file XrdSecProtocolpwd.hh.

Constructor & Destructor Documentation

◆ XrdSecProtocolpwd()

XrdSecProtocolpwd::XrdSecProtocolpwd ( int opts,
const char * hname,
XrdNetAddrInfo & endPoint,
const char * parms = 0 )

Definition at line 252 of file XrdSecProtocolpwd.cc.

254 : XrdSecProtocol("pwd")
255{
256 // Default constructor
257 EPNAME("XrdSecProtocolpwd");
258
259 if (QTRACE(Authen)) { PRINT("constructing: "<<this); }
260
261 // Create instance of the handshake vars
262 if ((hs = new pwdHSVars())) {
263 // Update time stamp
264 hs->TimeStamp = time(0);
265 // Local handshake variables
266 hs->CryptoMod = ""; // crypto module in use
267 hs->User = ""; // remote username
268 hs->Tag.resize(256); // tag for credentials
269 hs->RemVers = -1; // Version run by remote counterpart
270 hs->CF = 0; // crypto factory
271 hs->Hcip = 0; // handshake cipher
272 hs->Rcip = 0; // reference cipher
273 hs->ID = ""; // Handshake ID (dummy for clients)
274 hs->Cref = 0; // Cache reference
275 hs->Pent = 0; // Pointer to relevant file entry
276 hs->RtagOK = 0; // Rndm tag checked / not checked
277 hs->Tty = (isatty(0) == 0 || isatty(1) == 0) ? 0 : 1;
278 hs->Step = 0; // Current step
279 hs->LastStep = 0; // Step required at previous iteration
280 } else {
281 PRINT("could not create handshake vars object");
282 }
283
284 // Used by servers to store forwarded credentials
285 clientCreds = 0;
286
287 // Save host name and address
288 if (hname) {
289 Entity.host = strdup(hname);
290 } else {
291 NOTIFY("warning: host name undefined");
292 }
293 epAddr = endPoint;
294 Entity.addrInfo = &epAddr;
295 // Init client name
296 CName[0] = '?'; CName[1] = '\0';
297
298 //
299 // Notify, if required
300 DEBUG("constructing: host: "<<hname);
301 DEBUG("p: "<<XrdSecPROTOIDENT<<", plen: "<<XrdSecPROTOIDLEN);
302 //
303 // basic settings
304 options = opts;
305
306 //
307 // Mode specific initializations
308 if (Server) {
309 srvMode = 1;
310 DEBUG("mode: server");
311 } else {
312 srvMode = 0;
313 DEBUG("mode: client");
314 if (AutoLogin > 0) {
315 DEBUG("using autologin file: "<<PFAlog.Name());
316 if (AutoLogin > 1) {
317 DEBUG("running in update-autologin mode");
318 }
319 }
320 if (VeriSrv > 0) {
321 DEBUG("server verification ON");
322 } else {
323 DEBUG("server verification OFF");
324 }
325 // Decode received buffer
326 if (parms) {
327 XrdOucString p("&P=pwd,");
328 p += parms;
329 hs->Parms = new XrdSutBuffer(p.c_str(), p.length());
330 }
331 }
332
333 // We are done
334 String vers = Version;
335 vers.insert('.',vers.length()-2);
336 vers.insert('.',vers.length()-5);
337 DEBUG("object created: v"<<vers.c_str());
338}
#define DEBUG(x)
#define EPNAME(x)
#define QTRACE(act)
#define PRINT(y)
static const kXR_int32 Version
XrdOucString String
#define XrdSecPROTOIDLEN
#define XrdSecPROTOIDENT
#define NOTIFY(y)
struct myOpts opts
void insert(const int i, int start=-1)
int length() const
const char * c_str() const
XrdSecEntity Entity
XrdSecProtocol(const char *pName)
Constructor.

References XrdSecProtocol::XrdSecProtocol(), XrdOucString::c_str(), DEBUG, XrdSecProtocol::Entity, EPNAME, XrdOucString::insert(), XrdOucString::length(), NOTIFY, opts, PRINT, QTRACE, Version, XrdSecPROTOIDENT, and XrdSecPROTOIDLEN.

Here is the call graph for this function:

◆ ~XrdSecProtocolpwd()

virtual XrdSecProtocolpwd::~XrdSecProtocolpwd ( )
inlinevirtual

Definition at line 298 of file XrdSecProtocolpwd.hh.

298{} // Delete() does it all

Member Function Documentation

◆ Authenticate()

int XrdSecProtocolpwd::Authenticate ( XrdSecCredentials * cred,
XrdSecParameters ** parms,
XrdOucErrInfo * einfo = 0 )
virtual

Authenticate a client.

Parameters
credCredentials supplied by the client.
parmsPlace where the address of additional authentication data is to be placed for another autrhentication handshake.
einfoThe error information object where error messages should be placed. The messages are returned to the client. Should einfo be null, messages should be written to stderr.
Returns
> 0 -> parms present (more authentication needed) = 0 -> Entity present (authentication succeeded) < 0 -> einfo present (error has occurred)

Implements XrdSecProtocol.

Definition at line 1169 of file XrdSecProtocolpwd.cc.

1172{
1173 //
1174 // Check if we have any credentials or if no credentials really needed.
1175 // In either case, use host name as client name
1176 EPNAME("Authenticate");
1177
1178 //
1179 // If cred buffer is two small or empty assume host protocol
1180 if (cred->size <= (int)XrdSecPROTOIDLEN || !cred->buffer) {
1181 strncpy(Entity.prot, "host", sizeof(Entity.prot));
1182 return 0;
1183 }
1184
1185 // Handshake vars container must be initialized at this point
1186 if (!hs)
1187 return ErrS(String("none"),ei,0,0,0,kPWErrError,
1188 "handshake var container missing",
1189 "protocol initialization problems");
1190 hs->ErrMsg = "";
1191 //
1192 // Update time stamp
1193 hs->TimeStamp = time(0);
1194
1195 //
1196 // ID of this handshaking
1197 hs->ID = Entity.tident;
1198 DEBUG("handshaking ID: " << hs->ID);
1199
1200 // Local vars
1201 int i = 0;
1202 int kS_rc = kpST_more;
1203 int rc = 0;
1204 int entst = 0;
1205 int nextstep = 0;
1206 int ctype = kpCT_normal;
1207 char *bpub = 0, *bpid = 0;
1208 int lpub = 0;
1209 const char *stepstr = 0;
1210 String Message;
1212 String Host;
1213 String SrvPuKExp;
1214 String Salt;
1215 String RndmTag;
1216 String ClntMsg(256);
1217 // Buffer related
1218 XrdSutBuffer *bpar = 0; // Global buffer
1219 XrdSutBuffer *bmai = 0; // Main buffer
1220 XrdSutBucket *bck = 0; // Generic bucket
1221 // The local status info
1222 pwdStatus_t SessionSt = { 0, 0, 0};
1223
1224 //
1225 // Unlocks automatically returning
1226 XrdSysMutexHelper pwdGuard(&pwdContext);
1227 //
1228 // Decode received buffer
1229 if (!(bpar = new XrdSutBuffer((const char *)cred->buffer,cred->size)))
1230 return ErrS(hs->ID,ei,0,0,0,kPWErrDecodeBuffer,"global",stepstr);
1231 //
1232 // Check protocol ID name
1233 if (strcmp(bpar->GetProtocol(),XrdSecPROTOIDENT))
1234 return ErrS(hs->ID,ei,bpar,bmai,0,kPWErrBadProtocol,stepstr);
1235 //
1236 // The step indicates what we are supposed to do
1237 hs->Step = bpar->GetStep();
1238 stepstr = ClientStepStr(hs->Step);
1239 // Dump, if requested
1240 if (QTRACE(Dump)) {
1241 bpar->Dump(stepstr);
1242 }
1243
1244 //
1245 // Find first crypto module to be used
1246 if (ParseCrypto(bpar) != 0)
1247 return ErrS(hs->ID,ei,bpar,0,0,kPWErrLoadCrypto,stepstr);
1248 //
1249 // Parse input buffer
1250 if (ParseServerInput(bpar, &bmai, ClntMsg) == -1) {
1251 PRINT(ClntMsg);
1252 return ErrS(hs->ID,ei,bpar,bmai,0,kPWErrParseBuffer,ClntMsg.c_str(),stepstr);
1253 }
1254 //
1255 // Get handshake status
1256 if ((bck = bmai->GetBucket(kXRS_status))) {
1257 int pst = 0;
1258 memcpy(&pst,bck->buffer,sizeof(pwdStatus_t));
1259 pst = ntohl(pst);
1260 memcpy(&SessionSt, &pst, sizeof(pwdStatus_t));
1261 bmai->Deactivate(kXRS_status);
1262 } else {
1263 NOTIFY("no bucket kXRS_status found in main buffer");
1264 }
1265 hs->Tty = SessionSt.options & kOptsClntTty;
1266 //
1267 // Client name
1268 unsigned int ulen = hs->User.length();
1269 ulen = (ulen > sizeof(CName)-1) ? sizeof(CName)-1 : ulen;
1270 if (ulen)
1271 strcpy(CName, hs->User.c_str());
1272 // And set link to entity
1273 Entity.name = strdup(CName);
1274
1275 //
1276 // Version
1277 DEBUG("version run by client: "<< hs->RemVers);
1278 //
1279 // Dump, if requested
1280 if (QTRACE(Dump)) {
1281 bmai->Dump("main IN");
1282 }
1283 //
1284 // Check random challenge
1285 if (!CheckRtag(bmai, ClntMsg))
1286 return ErrS(hs->ID,ei,bpar,bmai,0,kPWErrBadRndmTag,stepstr,ClntMsg.c_str());
1287 //
1288 // Check also host / time stamp (it will be done only if really neede)
1289 if (!CheckTimeStamp(bmai, TimeSkew, ClntMsg))
1290 return ErrS(hs->ID,ei,bpar,bmai,0,kPWErrBadRndmTag,stepstr,ClntMsg.c_str());
1291 //
1292 // Now action depens on the step
1293 bool savecreds = (SessionSt.options & kOptsExpCred);
1294 switch (hs->Step) {
1295
1296 case kXPC_verifysrv:
1297 //
1298 // Client required us to sign a random challenge: this is done
1299 // in AddSerialized, so nothing to do here
1300 nextstep = kXPS_signedrtag;
1301 break;
1302
1303 case kXPC_signedrtag:
1304 //
1305 // Client signed the random challenge we sent: if we are here,
1306 // everything was fine
1307 kS_rc = kpST_ok;
1308 nextstep = kXPS_none;
1309 break;
1310
1311 case kXPC_failureack:
1312 //
1313 // Client acknowledged failure
1314 kS_rc = kpST_error;
1315 nextstep = kXPS_none;
1316 break;
1317
1318 case kXPC_autoreg:
1319 //
1320 // Client has lost the key or requested auto-registration: we
1321 // check the username: if it has a good entry or it is allowed
1322 // to auto-register (the check is done in QueryUser) we send
1323 // the public part of the key; otherwise we fail
1324 rc = QueryUser(entst, ClntMsg);
1325 if (rc < 0 || (entst == kPFE_disabled))
1326 return ErrS(hs->ID,ei,bpar,bmai,0, kPWErrBadCreds,
1327 DefError.c_str(),stepstr);
1328 //
1329 // We have to send the public key
1330 for (i = 0; i < ncrypt; i++) {
1331 if (refcip[i]) {
1332 //
1333 // Extract buffer with public info for the cipher agreement
1334 if (!(bpub = refcip[i]->Public(lpub)))
1335 return ErrS(hs->ID,ei,bpar,bmai,0, kPWErrNoPublic,
1336 "session",stepstr);
1337 bpid = new char[lpub+5];
1338 if (bpid) {
1339 char cid[5] = {0};
1340 sprintf(cid,"%d",cryptID[i]);
1341 memcpy(bpid,cid,5);
1342 memcpy(bpid+5, bpub, lpub);
1343 //
1344 // Add it to the global list
1345 if (bmai->AddBucket(bpid,lpub+5,kXRS_puk) != 0)
1346 return ErrS(hs->ID,ei,bpar,bmai,0, kPWErrAddBucket,
1347 "main",stepstr);
1348 } else
1349 return ErrS(hs->ID,ei,bpar,bmai,0, kPWErrError,
1350 "out-of-memory",stepstr);
1351 SafeDelArray(bpub); // bpid is taken by the bucket
1352 }
1353 }
1354 // client should now go through a complete login
1355 nextstep = kXPS_puk;
1356 break;
1357
1358 case kXPC_normal:
1359 case kXPC_creds:
1360if (hs->Step == kXPC_normal)
1361 {
1362 //
1363 // Complete login sequence: check user and creds
1364 if (QueryUser(entst,ClntMsg) != 0)
1365 return ErrS(hs->ID,ei,bpar,bmai,0, kPWErrBadCreds,
1366 ": user ",hs->User.c_str(),stepstr);
1367 // Nothing to do, if disabled
1368 if (entst == kPFE_disabled)
1369 return ErrS(hs->ID,ei,bpar,bmai,0, kPWErrBadCreds,
1370 ": user ",hs->User.c_str(),stepstr);
1371
1372 if (entst == kPFE_expired || entst == kPFE_onetime) {
1373 // New credentials should asked upon success first check
1374 SessionSt.options |= kOptsExpCred;
1375 }
1376 if (entst == kPFE_crypt) {
1377 // User credentials are either in crypt form (private or
1378 // system ones) or of AFS type; in case of failure
1379 // this flag allows the client to send the right creds
1380 // at next iteration
1381 if (ClntMsg.beginswith("afs:")) {
1382 SessionSt.options |= kOptsAFSPwd;
1383 } else
1384 SessionSt.options |= kOptsCrypPwd;
1385 // Reset the message
1386 ClntMsg = "";
1387 }
1388 // Creds, if any, should be checked, unles we allow auto-registration
1389 savecreds = (entst != kPFE_allowed) ? 0 : 1;
1390 }
1391
1392// case kXPC_creds: (falls into here from _normal)
1393 //
1394 // Final login sequence: extract and check creds
1395 // Extract credentials from main buffer
1396 if (!(bck = bmai->GetBucket(kXRS_creds))) {
1397 //
1398 // If credentials are missing, require them
1399 kS_rc = kpST_more;
1400 nextstep = kXPS_credsreq;
1401 break;
1402 }
1403 //
1404 // If we required new credentials at previous step, just save them
1405 if (savecreds) {
1406 if (SaveCreds(bck) != 0) {
1407 ClntMsg = "Warning: could not correctly update credentials database";
1408 }
1409 kS_rc = kpST_ok;
1410 nextstep = kXPS_none;
1411 bmai->Deactivate(kXRS_creds);
1412 break;
1413 }
1414 //
1415 // Credential type
1416 ctype = kpCT_normal;
1417 if (SessionSt.options & kOptsCrypPwd)
1418 ctype = kpCT_crypt;
1419 else if (SessionSt.options & kOptsAFSPwd) {
1420 ctype = kpCT_afs;
1421 String afsInfo;
1422 XrdSutBucket *bafs = bmai->GetBucket(kXRS_afsinfo);
1423 if (bafs)
1424 bafs->ToString(afsInfo);
1425 if (afsInfo == "c")
1426 ctype = kpCT_afsenc;
1427 }
1428 //
1429 // Check credentials
1430 if (!CheckCreds(bck, ctype)) {
1431 //
1432 // Count temporary failures
1433 (hs->Cref->cnt)++;
1434 // Reset expired credentials flag
1435 SessionSt.options &= ~kOptsExpCred;
1436 // Repeat if not too many attempts
1437 ClntMsg = DefError;
1438 if (hs->Cref->cnt < MaxPrompts) {
1439 // Set next step to credential request
1440 nextstep = kXPS_credsreq;
1441 kS_rc = kpST_more;
1442 // request again creds
1443 if (hs->Pent->status == kPFE_crypt) {
1444 SessionSt.ctype = kpCT_crypt;
1445 if (ctype == kpCT_afs || ctype == kpCT_afsenc) {
1446 SessionSt.ctype = kpCT_afs;
1447 String afsinfo = hs->ErrMsg;
1448 bmai->UpdateBucket(afsinfo, kXRS_afsinfo);
1449 }
1450 ClntMsg = "";
1451 } else {
1452 SessionSt.ctype = kpCT_normal;
1453 ClntMsg = "insufficient credentials";
1454 }
1455 } else {
1456 // We communicate failure
1457 kS_rc = kpST_more;
1458 nextstep = kXPS_failure;
1459 // Count failures
1460 (hs->Pent->cnt)++;
1461 // Count failures
1462 hs->Pent->mtime = (kXR_int32)time(0);
1463 // Flush cache content to source file
1464 XrdSysPrivGuard priv(getuid(), getgid());
1465 if (priv.Valid()) {
1466 if (cacheAdmin.Flush() != 0) {
1467 PRINT("WARNING: some problem flushing to admin"
1468 " file after updating "<<hs->Pent->name);
1469 }
1470 }
1471 }
1472 } else {
1473 // Reset counter for temporary failures
1474 hs->Cref->cnt = 0;
1475 // Reset counter in file if needed
1476 if (hs->Pent->cnt > 0) {
1477 hs->Pent->cnt = 0;
1478 // Count failures
1479 hs->Pent->mtime = (kXR_int32)time(0);
1480 // Flush cache content to source file
1481 XrdSysPrivGuard priv(getuid(), getgid());
1482 if (priv.Valid()) {
1483 if (cacheAdmin.Flush() != 0) {
1484 PRINT("WARNING: some problem flushing to admin"
1485 " file after updating "<<hs->Pent->name);
1486 }
1487 }
1488 }
1489 kS_rc = kpST_ok;
1490 nextstep = kXPS_none;
1491 if (SessionSt.options & kOptsExpCred ||
1492 // Client requested a pwd change
1493 SessionSt.options & kOptsChngPwd) {
1494 kS_rc = kpST_more;
1495 nextstep = kXPS_credsreq;
1496 if (SessionSt.options & kOptsExpCred) {
1497 ClntMsg = "Credentials expired";
1498 } else if (SessionSt.options & kOptsChngPwd) {
1499 ClntMsg = "Password change requested";
1500 }
1501 // request new creds
1502 SessionSt.ctype = kpCT_new;
1503 // So we can save at next round
1504 SessionSt.options |= kOptsExpCred;
1505 }
1506 // Create buffer to keep the credentials, if required
1507 if (KeepCreds) {
1508 int sz = bck->size+5;
1509 char *buf = (char *) malloc(sz);
1510 if (buf) {
1511 memcpy(buf, "&pwd", 4);
1512 buf[4] = 0;
1513 memcpy(buf+5, bck->buffer, bck->size);
1514 // Put in hex
1515 char *out = new char[2*sz+1];
1516 XrdSutToHex(buf, sz, out);
1517 // Cleanup any existing info
1518 SafeDelete(clientCreds);
1519 clientCreds = new XrdSecCredentials(out, 2*sz+1);
1520 }
1521 }
1522 // Export creds to a file, if required
1523 if (FileExpCreds.length() > 0) {
1524 if (ExportCreds(bck) != 0)
1525 PRINT("WARNING: some problem exporting creds to file;"
1526 " template is :"<<FileExpCreds);
1527 }
1528 }
1529 // We will not use again these credentials
1530 bmai->Deactivate(kXRS_creds);
1531
1532 break;
1533
1534 default:
1535 return ErrS(hs->ID,ei,bpar,bmai,0, kPWErrBadOpt, stepstr);
1536 }
1537
1538 //
1539 // If strong signature checking is required add random tag
1540 if (kS_rc == kpST_ok) {
1541 if (VeriClnt == 2 && !(hs->RtagOK)) {
1542 // Send only the random tag to sign
1543 nextstep = kXPS_rtag;
1544 kS_rc = kpST_more;
1545 }
1546 }
1547
1548 //
1549 // If we need additional info but the client caa not reply, just fail
1550 if (kS_rc == kpST_more && !(hs->Tty)) {
1551 PRINT("client cannot reply to additional request: failure");
1552 // Deactivate everything
1553 bpar->Deactivate(-1);
1554 bmai->Deactivate(-1);
1555 kS_rc = kpST_error;
1556 }
1557 //
1558 if (kS_rc == kpST_more) {
1559 //
1560 // Add message to client
1561 if (ClntMsg.length() > 0)
1562 if (bmai->AddBucket(ClntMsg,kXRS_message) != 0) {
1563 PRINT("problems adding bucket with message for client");
1564 }
1565 //
1566 // We set some options in the option field of a pwdStatus_t structure
1567 int *pst = (int *) new char[sizeof(pwdStatus_t)];
1568 memcpy(pst,&SessionSt,sizeof(pwdStatus_t));
1569 *pst = htonl(*pst);
1570 if (bmai->AddBucket((char *)pst,sizeof(pwdStatus_t), kXRS_status) != 0) {
1571 PRINT("problems adding bucket kXRS_status");
1572 }
1573 //
1574 // Serialize, encrypt and add to the global list
1575 if (AddSerialized('s', nextstep, hs->ID,
1576 bpar, bmai, kXRS_main, hs->Hcip) != 0)
1577 return ErrS(hs->ID,ei,bpar,bmai,0, kPWErrSerialBuffer,
1578 "main / session cipher",stepstr);
1579 //
1580 // Serialize the global buffer
1581 char *bser = 0;
1582 int nser = bpar->Serialized(&bser,'f');
1583 //
1584 // Dump, if requested
1585 if (QTRACE(Dump)) {
1586 bpar->Dump(ServerStepStr(bpar->GetStep()));
1587 bmai->Dump("Main OUT");
1588 }
1589 //
1590 // Create buffer for client
1591 *parms = new XrdSecParameters(bser,nser);
1592 } else {
1593 //
1594 // Cleanup handshake vars
1595 SafeDelete(hs);
1596 }
1597 //
1598 // We may release the buffers now
1599 REL2(bpar,bmai);
1600 //
1601 // All done
1602 return kS_rc;
1603}
int kXR_int32
Definition XPtypes.hh:89
XrdSecBuffer XrdSecParameters
XrdSecBuffer XrdSecCredentials
static const char * ClientStepStr(int kclt)
static const char * ServerStepStr(int ksrv)
static const short kOptsChngPwd
static const short kOptsExpCred
static const short kOptsAFSPwd
static const short kOptsCrypPwd
static const short kOptsClntTty
#define SafeDelete(x)
#define REL2(x, y)
@ kPWErrParseBuffer
@ kPWErrBadOpt
@ kPWErrBadCreds
@ kPWErrSerialBuffer
@ kPWErrNoPublic
@ kPWErrBadProtocol
@ kPWErrLoadCrypto
@ kPWErrBadRndmTag
@ kPWErrDecodeBuffer
@ kPWErrError
@ kPWErrAddBucket
@ kpST_ok
@ kpST_more
@ kpST_error
@ kXPC_failureack
@ kXPC_autoreg
@ kXPC_signedrtag
@ kXPC_normal
@ kXPC_creds
@ kXPC_verifysrv
#define SafeDelArray(x)
@ kpCT_normal
@ kpCT_crypt
@ kpCT_afsenc
@ kXPS_credsreq
@ kXPS_failure
@ kXPS_none
@ kXPS_signedrtag
@ kXPS_rtag
XrdOucString CryptList
void ParseCrypto()
int XrdSutToHex(const char *in, int lin, char *out)
Definition XrdSutAux.cc:235
@ kXRS_afsinfo
Definition XrdSutAux.hh:84
@ kXRS_message
Definition XrdSutAux.hh:68
@ kXRS_puk
Definition XrdSutAux.hh:61
@ kXRS_status
Definition XrdSutAux.hh:72
@ kXRS_main
Definition XrdSutAux.hh:58
@ kXRS_creds
Definition XrdSutAux.hh:67
@ kPFE_allowed
@ kPFE_disabled
@ kPFE_onetime
@ kPFE_expired
@ kPFE_crypt
kXR_int32 size
void ToString(XrdOucString &s)
int AddBucket(char *bp=0, int sz=0, int ty=0)
int UpdateBucket(const char *bp, int sz, int ty)
int Serialized(char **buffer, char opt='n')
const char * GetProtocol() const
void Dump(const char *stepstr=0, bool all=false)
int GetStep() const
XrdSutBucket * GetBucket(kXR_int32 type, const char *tag=0)
void Deactivate(kXR_int32 type)
char * buffer
Pointer to the buffer.
int size
Size of the buffer or length of data in the buffer.

References XrdSutBuffer::AddBucket(), XrdOucString::beginswith(), XrdSecBuffer::buffer, XrdSutBucket::buffer, XrdOucString::c_str(), ClientStepStr(), CryptList, pwdStatus_t::ctype, XrdSutBuffer::Deactivate(), DEBUG, XrdSutBuffer::Dump(), XrdSecProtocol::Entity, EPNAME, XrdSutBuffer::GetBucket(), XrdSutBuffer::GetProtocol(), XrdSutBuffer::GetStep(), kOptsAFSPwd, kOptsChngPwd, kOptsClntTty, kOptsCrypPwd, kOptsExpCred, kpCT_afs, kpCT_afsenc, kpCT_crypt, kpCT_new, kpCT_normal, kPFE_allowed, kPFE_crypt, kPFE_disabled, kPFE_expired, kPFE_onetime, kpST_error, kpST_more, kpST_ok, kPWErrAddBucket, kPWErrBadCreds, kPWErrBadOpt, kPWErrBadProtocol, kPWErrBadRndmTag, kPWErrDecodeBuffer, kPWErrError, kPWErrLoadCrypto, kPWErrNoPublic, kPWErrParseBuffer, kPWErrSerialBuffer, kXPC_autoreg, kXPC_creds, kXPC_failureack, kXPC_normal, kXPC_signedrtag, kXPC_verifysrv, kXPS_credsreq, kXPS_failure, kXPS_none, kXPS_puk, kXPS_rtag, kXPS_signedrtag, kXRS_afsinfo, kXRS_creds, kXRS_main, kXRS_message, kXRS_puk, kXRS_status, XrdOucString::length(), NOTIFY, pwdStatus_t::options, ParseCrypto(), PRINT, QTRACE, REL2, SafeDelArray, SafeDelete, XrdSutBuffer::Serialized(), ServerStepStr(), XrdSecBuffer::size, XrdSutBucket::size, XrdSutBucket::ToString(), XrdSutBuffer::UpdateBucket(), XrdSysPrivGuard::Valid(), XrdSecPROTOIDENT, XrdSecPROTOIDLEN, and XrdSutToHex().

Here is the call graph for this function:

◆ Delete()

void XrdSecProtocolpwd::Delete ( )
virtual

Delete the protocol object. DO NOT use C++ delete() on this object.

Implements XrdSecProtocol.

Definition at line 854 of file XrdSecProtocolpwd.cc.

855{
856 // Deletes the protocol
857 if (Entity.host) free(Entity.host);
858 // Cleanup the handshake variables, if still there
859 SafeDelete(hs);
860 delete this;
861}

References XrdSecProtocol::Entity, and SafeDelete.

◆ EnableTracing()

XrdOucTrace * XrdSecProtocolpwd::EnableTracing ( )
static

Definition at line 1609 of file XrdSecProtocolpwd.cc.

1610{
1611 // Initiate error logging and tracing
1612
1613 eDest.logger(&Logger);
1614 PWDTrace = new XrdOucTrace(&eDest);
1615 return PWDTrace;
1616}

Referenced by XrdSecProtocolpwdInit().

Here is the caller graph for this function:

◆ getCredentials()

XrdSecCredentials * XrdSecProtocolpwd::getCredentials ( XrdSecParameters * parm = 0,
XrdOucErrInfo * einfo = 0 )
virtual

Generate client credentials to be used in the authentication process.

Parameters
parmPointer to the information returned by the server either in the initial login response or the authmore response.
einfoThe error information object where error messages should be placed. The messages are returned to the client. Should einfo be null, messages should be written to stderr.
Returns
Success: Pointer to credentials to sent to the server. The caller is responsible for deleting the object. Failure: Null pointer with einfo, if supplied, containing the reason for the failure.

Implements XrdSecProtocol.

Definition at line 870 of file XrdSecProtocolpwd.cc.

872{
873 // Query client for the password; remote username and host
874 // are specified in 'parm'. File '.rootnetrc' is checked.
875 EPNAME("getCredentials");
876
877 // If we are a server the only reason to be here is to get the forwarded
878 // or saved client credentials
879 if (srvMode) {
880 XrdSecCredentials *creds = 0;
881 if (clientCreds) {
882 // Duplicate the buffer (otherwise it will get deleted ...)
883 int sz = clientCreds->size;
884 char *nbuf = (char *) malloc(sz);
885 if (nbuf) {
886 memcpy(nbuf, clientCreds->buffer, sz);
887 creds = new XrdSecCredentials(nbuf, sz);
888 }
889 }
890 return creds;
891 }
892
893 // Handshake vars conatiner must be initialized at this point
894 if (!hs)
895 return ErrC(ei,0,0,0,kPWErrError,
896 "handshake var container missing","getCredentials");
897 hs->ErrMsg = "";
898
899 //
900 // Nothing to do if buffer is empty and not filled during construction
901 if ((!parm && !hs->Parms) || (parm && (!(parm->buffer) || parm->size <= 0)))
902 return ErrC(ei,0,0,0,kPWErrNoBuffer,"missing parameters","getCredentials");
903
904 // Count interations
905 (hs->Iter)++;
906
907 // Update time stamp
908 hs->TimeStamp = time(0);
909
910 // Local vars
911 int nextstep = 0;
912 const char *stepstr = 0;
913 kXR_int32 status = 0;
914 char *bpub = 0;
915 int lpub = 0;
916 String CryptList = "";
917 String Host = "";
918 String RemID = "";
919 String Emsg;
920 String specID = "";
921 // Buffer / Bucket related
922 XrdSutBucket *bck = 0;
923 XrdSutBuffer *bpar = 0; // Global buffer
924 XrdSutBuffer *bmai = 0; // Main buffer
925 // Session status
926 pwdStatus_t SessionSt;
927 memset(&SessionSt,0,sizeof(SessionSt));
928
929 //
930 // Unlocks automatically returning
931 XrdSysMutexHelper pwdGuard(&pwdContext);
932 //
933 // Decode received buffer
934 bpar = hs->Parms;
935 if (!bpar && !(bpar = new XrdSutBuffer((const char *)parm->buffer,parm->size)))
936 return ErrC(ei,0,0,0,kPWErrDecodeBuffer,"global",stepstr);
937 // Ownership has been transferred
938 hs->Parms = 0;
939 //
940 // Check protocol ID name
941 if (strcmp(bpar->GetProtocol(),XrdSecPROTOIDENT))
942 return ErrC(ei,bpar,bmai,0,kPWErrBadProtocol,stepstr);
943 //
944 // The step indicates what we are supposed to do
945 hs->Step = (bpar->GetStep()) ? bpar->GetStep() : kXPS_init;
946 stepstr = ServerStepStr(hs->Step);
947 // Dump, if requested
948 if (QTRACE(Dump)) {
949 bpar->Dump(stepstr);
950 }
951 //
952 // Find first crypto module to be used
953 if (ParseCrypto(bpar) != 0)
954 return ErrC(ei,bpar,0,0,kPWErrLoadCrypto,stepstr);
955 //
956 // Parse input buffer
957 if (ParseClientInput(bpar, &bmai, Emsg) == -1) {
958 PRINT(Emsg);
959 return ErrC(ei,bpar,bmai,0,kPWErrParseBuffer,Emsg.c_str(),stepstr);
960 }
961 //
962 // Version
963 DEBUG("version run by server: "<< hs->RemVers);
964 //
965 // Dump what we got
966 if (QTRACE(Dump)) {
967 bmai->Dump("Main IN");
968 }
969 //
970 // Print server messages, if any
971 if (hs->Iter > 1) {
972 bmai->Message();
974 }
975 //
976 // Check random challenge
977 if (!CheckRtag(bmai, Emsg))
978 return ErrC(ei,bpar,bmai,0,kPWErrBadRndmTag,Emsg.c_str(),stepstr);
979
980 //
981 // Get the status bucket, if any
982 if ((bck = bmai->GetBucket(kXRS_status))) {
983 int pst = 0;
984 memcpy(&pst,bck->buffer,sizeof(pwdStatus_t));
985 pst = ntohl(pst);
986 memcpy(&SessionSt, &pst, sizeof(pwdStatus_t));
987 bmai->Deactivate(kXRS_status);
988 } else {
989 SessionSt.ctype = kpCT_normal;
990 }
991 //
992 // Now action depens on the step
993 nextstep = kXPC_none;
994 switch (hs->Step) {
995
996 case kXPS_init: // The following 3 cases may fall through
997 case kXPS_puk:
998 case kXPS_signedrtag: // (after kXRC_verifysrv)
999if (hs->Step == kXPS_init)
1000 {
1001 //
1002 // Add bucket with cryptomod to the global list
1003 // (This must be always visible from now on)
1004 if (bpar->AddBucket(hs->CryptoMod,kXRS_cryptomod) != 0)
1005 return ErrC(ei,bpar,bmai,0,
1007 //
1008 // Add bucket with our version to the main list
1009 if (bmai->MarshalBucket(kXRS_version,(kXR_int32)(Version)) != 0)
1010 return ErrC(ei,bpar,bmai,0, kPWErrCreateBucket,
1011 XrdSutBuckStr(kXRS_version),"(main list)",stepstr);
1012 //
1013 // We set some options in the option field of a pwdStatus_t structure
1014 if (hs->Tty || (AutoLogin > 0))
1015 SessionSt.options = kOptsClntTty;
1016 }
1017// case kXPS_puk:
1018if ((hs->Step == kXPS_init) || (hs->Step == kXPS_puk))
1019 {
1020 // After auto-reg request, server puk have been saved in ParseClientInput:
1021 // we need to start a full normal login now
1022
1023 //
1024 // If we have a session cipher we extract the public part
1025 // and add to the main packet for transmission to server
1026 if (hs->Hcip) {
1027 //
1028 // Extract buffer with public info for the cipher agreement
1029 if (!(bpub = hs->Hcip->Public(lpub)))
1030 return ErrC(ei,bpar,bmai,0,
1031 kPWErrNoPublic,"session",stepstr);
1032 //
1033 // Add it to the global list
1034 if (bpar->UpdateBucket(bpub,lpub,kXRS_puk) != 0)
1035 return ErrC(ei,bpar,bmai,0, kPWErrAddBucket,
1036 XrdSutBuckStr(kXRS_puk),"global",stepstr);
1037 SafeDelArray(bpub);
1038 //
1039 // If we are requiring server verification of puk ownership
1040 // we are done for this step
1041 if (VeriSrv == 1) {
1042 nextstep = kXPC_verifysrv;
1043 break;
1044 }
1045 }
1046 }
1047// case kXPS_signedrtag: // (after kXRC_verifysrv)
1048 //
1049 // Add the username
1050 if (hs->User.length()) {
1051 if (bmai->AddBucket(hs->User,kXRS_user) != 0)
1052 return ErrC(ei,bpar,bmai,0, kPWErrDuplicateBucket,
1053 XrdSutBuckStr(kXRS_user),stepstr);
1054 } else
1055 return ErrC(ei,bpar,bmai,0, kPWErrNoUser,stepstr);
1056
1057 //
1058 // If we do not have a session cipher, the only thing we can
1059 // try is auto-registration
1060 if (!(hs->Hcip)) {
1061 nextstep = kXPC_autoreg;
1062 break;
1063 }
1064
1065 //
1066 // Normal attempt: add credentials
1067 status = kpCT_normal;
1068 if (hs->SysPwd == 1)
1069 status = kpCT_crypt;
1070 if (hs->SysPwd == 2)
1071 status = kpCT_afs;
1072 if (!(bck = QueryCreds(bmai, (AutoLogin > 0), status)))
1073 return ErrC(ei,bpar,bmai,0, kPWErrQueryCreds,
1074 hs->Tag.c_str(),stepstr);
1075 bmai->AddBucket(bck);
1076 //
1077 // Tell the server we want to change the password, if so
1078 if (hs->Pent->status == kPFE_onetime)
1079 SessionSt.options |= kOptsChngPwd;
1080 //
1081 nextstep = kXPC_normal;
1082 break;
1083
1084 case kXPS_credsreq:
1085 //
1086 // If this is not the first time, during the handshake, that
1087 // we query credentials, any save buffer must insufficient,
1088 // so invalidate it
1089 if (hs->Pent)
1090 hs->Pent->cnt = 1;
1091 //
1092 // Server requires additional credentials: the status bucket
1093 // tells us what she wants exactly
1094 status = SessionSt.ctype;
1095 if (!(bck = QueryCreds(bmai, 0, status)))
1096 return ErrC(ei,bpar,bmai,0, kPWErrQueryCreds,
1097 hs->Tag.c_str(),stepstr);
1098 bmai->AddBucket(bck);
1099 //
1100 nextstep = kXPC_creds;
1101 break;
1102
1103 case kXPS_failure:
1104 //
1105 // Failure: invalidate cache
1106 hs->Pent->buf1.SetBuf();
1107 hs->Pent->buf2.SetBuf();
1108 //
1109 nextstep = kXPC_failureack;
1110 break;
1111
1112 case kXPS_newpuk:
1113 //
1114 // New server puk have been saved in ParseClientInput: we
1115 // just need to sign the random tag
1116 case kXPS_rtag:
1117 //
1118 // Not much to do: the random tag is signed in AddSerialized
1119 nextstep = kXPC_signedrtag;
1120 break;
1121
1122 default:
1123 return ErrC(ei,bpar,bmai,0, kPWErrBadOpt,stepstr);
1124 }
1125 //
1126 // Add / Update status
1127 int *pst = (int *) new char[sizeof(pwdStatus_t)];
1128 memcpy(pst,&SessionSt,sizeof(pwdStatus_t));
1129 *pst = htonl(*pst);
1130 if (bmai->AddBucket((char *)pst,sizeof(pwdStatus_t), kXRS_status) != 0) {
1131 PRINT("problems adding bucket kXRS_status");
1132 }
1133 //
1134 // Serialize and encrypt
1135 if (AddSerialized('c', nextstep, hs->ID,
1136 bpar, bmai, kXRS_main, hs->Hcip) != 0)
1137 return ErrC(ei,bpar,bmai,0,
1138 kPWErrSerialBuffer,"main",stepstr);
1139 //
1140 // Serialize the global buffer
1141 char *bser = 0;
1142 int nser = bpar->Serialized(&bser,'f');
1143
1144 if (QTRACE(Dump)) {
1145 bpar->Dump(ClientStepStr(bpar->GetStep()));
1146 bmai->Dump("Main OUT");
1147 }
1148 //
1149 // We may release the buffers now
1150 REL2(bpar,bmai);
1151 //
1152 // Return serialized buffer
1153 if (nser > 0) {
1154 DEBUG("returned " << nser <<" bytes of credentials");
1155 return new XrdSecCredentials(bser, nser);
1156 } else {
1157 DEBUG("problems with final serialization");
1158 return (XrdSecCredentials *)0;
1159 }
1160}
@ kPWErrNoBuffer
@ kPWErrQueryCreds
@ kPWErrDuplicateBucket
@ kPWErrNoUser
@ kPWErrCreateBucket
@ kXPC_none
@ kXPS_init
@ kXPS_newpuk
const char * XrdSutBuckStr(int kbck)
Definition XrdSutAux.cc:121
@ kXRS_user
Definition XrdSutAux.hh:65
@ kXRS_version
Definition XrdSutAux.hh:71
@ kXRS_cryptomod
Definition XrdSutAux.hh:57
void Message(const char *prepose=0)
kXR_int32 MarshalBucket(kXR_int32 type, kXR_int32 code)

References XrdSutBuffer::AddBucket(), XrdSecBuffer::buffer, XrdSutBucket::buffer, XrdOucString::c_str(), ClientStepStr(), CryptList, pwdStatus_t::ctype, XrdSutBuffer::Deactivate(), DEBUG, XrdSutBuffer::Dump(), EPNAME, XrdSutBuffer::GetBucket(), XrdSutBuffer::GetProtocol(), XrdSutBuffer::GetStep(), kOptsChngPwd, kOptsClntTty, kpCT_afs, kpCT_crypt, kpCT_normal, kPFE_onetime, kPWErrAddBucket, kPWErrBadOpt, kPWErrBadProtocol, kPWErrBadRndmTag, kPWErrCreateBucket, kPWErrDecodeBuffer, kPWErrDuplicateBucket, kPWErrError, kPWErrLoadCrypto, kPWErrNoBuffer, kPWErrNoPublic, kPWErrNoUser, kPWErrParseBuffer, kPWErrQueryCreds, kPWErrSerialBuffer, kXPC_autoreg, kXPC_creds, kXPC_failureack, kXPC_none, kXPC_normal, kXPC_signedrtag, kXPC_verifysrv, kXPS_credsreq, kXPS_failure, kXPS_init, kXPS_newpuk, kXPS_puk, kXPS_rtag, kXPS_signedrtag, kXRS_cryptomod, kXRS_main, kXRS_message, kXRS_puk, kXRS_status, kXRS_user, kXRS_version, XrdSutBuffer::MarshalBucket(), XrdSutBuffer::Message(), pwdStatus_t::options, ParseCrypto(), PRINT, QTRACE, REL2, SafeDelArray, XrdSutBuffer::Serialized(), ServerStepStr(), XrdSecBuffer::size, XrdSutBuffer::UpdateBucket(), Version, XrdSecPROTOIDENT, and XrdSutBuckStr().

Here is the call graph for this function:

◆ Init()

char * XrdSecProtocolpwd::Init ( pwdOptions o,
XrdOucErrInfo * erp )
static

Definition at line 341 of file XrdSecProtocolpwd.cc.

342{
343 // Static method to the configure the static part of the protocol
344 // Called once by XrdSecProtocolpwdInit
345 EPNAME("Init");
346 XrdSutPFCacheRef pfeRef;
347 char *Parms = 0;
348 //
349 // Debug an tracing
350 Debug = (opt.debug > -1) ? opt.debug : Debug;
351
352 // We must have the tracing object at this point
353 // (initialized in XrdSecProtocolgsiInit)
354 if (!pwdTrace) {
355 ErrF(erp,kPWErrInit,"tracing object (pwdTrace) not initialized! cannot continue");
356 return Parms;
357 }
358
359 // Set debug mask ... also for auxilliary libs
360 int trace = 0, traceSut = 0, traceCrypto = 0;
361 if (Debug >= 3) {
362 trace = cryptoTRACE_Dump;
363 traceSut = sutTRACE_Dump;
364 traceCrypto = cryptoTRACE_Dump;
365 PWDTrace->What = TRACE_ALL;
366 } else if (Debug >= 2) {
367 trace = cryptoTRACE_Debug;
368 traceSut = sutTRACE_Debug;
369 traceCrypto = cryptoTRACE_Debug;
370 PWDTrace->What = TRACE_Debug;
371 PWDTrace->What |= TRACE_Authen;
372 } else if (Debug >= 1) {
373 trace = cryptoTRACE_Debug;
374 traceSut = sutTRACE_Notify;
375 traceCrypto = cryptoTRACE_Notify;
376 PWDTrace->What = TRACE_Debug;
377 }
378
379 // ... also for auxilliary libs
380 XrdSutSetTrace(traceSut);
381 XrdCryptoSetTrace(traceCrypto);
382
383 // Get user info
384 struct passwd *pw;
385 XrdSysPwd thePwd(getuid(), &pw);
386
387 if (!pw) {
388 PRINT("no user info available - invalid ");
389 ErrF(erp, kPWErrInit, "could not get user info from pwuid");
390 return Parms;
391 }
392
393 //
394 // Operation mode
395 Server = (opt.mode == 's');
396
397 //
398 // Directory with admin pwd files
399 bool argdir = 0;
400 String infodir(512);
401 if (opt.dir) {
402 infodir = opt.dir;
403 // Expand
404 if (XrdSutExpand(infodir) != 0) {
405 PRINT("cannot expand "<<opt.dir);
406 infodir = "";
407 }
408 argdir = 1;
409 } else {
410 // use default dir $(HOME)/.<prefix>
411 infodir = XrdSutHome();
412 infodir += ("/." + Prefix);
413 }
414 if (!infodir.endswith("/")) infodir += "/";
415 //
416 // If defined, check existence of the infodir and admin file
417 if (infodir.length()) {
418 // Acquire the privileges, if needed
419 XrdSysPrivGuard priv(pw->pw_uid, pw->pw_gid);
420 if (priv.Valid()) {
421 struct stat st;
422 if (stat(infodir.c_str(),&st) == -1) {
423 if (errno == ENOENT) {
424 if (argdir) {
425 DEBUG("infodir non existing: "<<infodir.c_str());
426 } else {
427 DEBUG("creating infodir: "<<infodir.c_str());
428 if (XrdSutMkdir(infodir.c_str(),0777) != 0) {
429 DEBUG("cannot create infodir (errno: "<<errno<<")");
430 infodir = "";
431 argdir = 0;
432 }
433 }
434 } else {
435 DEBUG("cannot stat infodir "<<infodir<<" (errno: "<<errno<<")");
436 infodir = "";
437 argdir = 0;
438 }
439 }
440 }
441 }
442 DEBUG("using infodir: "<<infodir.c_str());
443
444 //
445 // Server specific options
446 if (Server) {
447 //
448 // Auto registration
449 AutoReg = (opt.areg > -1) ? opt.areg : AutoReg;
450 //
451 // Client verification level
452 VeriClnt = (opt.vericlnt > -1) ? opt.vericlnt : VeriClnt;
453 //
454 // Whether to check pwd files in users' $HOME
455 UserPwd = (opt.upwd > -1) ? opt.upwd : UserPwd;
456 //
457 // Whether to check system pwd files (if allowed)
458 SysPwd = (opt.syspwd > -1) ? opt.syspwd : SysPwd;
459 if (SysPwd) {
460 // Make sure this setting makes sense
461 if (pw) {
462#ifdef HAVE_SHADOWPW
463 // Acquire the privileges, if needed
464 XrdSysPrivGuard priv((uid_t) 0, (gid_t) 0);
465 if (priv.Valid()) {
466 // System V Rel 4 style shadow passwords
467 struct spwd *spw = getspnam(pw->pw_name);
468 if (!spw) {
469 SysPwd = 0;
470 DEBUG("no privileges to access shadow passwd file");
471 }
472 } else {
473 DEBUG("problems acquiring credentials"
474 " to access the system password file");
475 }
476#else
477 // Normal passwd file
478 if (!pw->pw_passwd &&
479 (pw->pw_passwd && strlen(pw->pw_passwd) <= 1)) {
480 SysPwd = 0;
481 DEBUG("no privileges to access system passwd file");
482 }
483#endif
484 } else
485 SysPwd = 0;
486 }
487 //
488 // Credential lifetime
489 LifeCreds = (opt.lifecreds > -1) ? opt.lifecreds : LifeCreds;
490 //
491 // Max number of failures
492 MaxFailures = (opt.maxfailures > -1) ? opt.maxfailures : MaxFailures;
493
494 //
495 // If defined, check existence of the infodir and admin file
496 if (infodir.length()) {
497 // Acquire the privileges, if needed
498 XrdSysPrivGuard priv(pw->pw_uid, pw->pw_gid);
499 if (priv.Valid()) {
500 struct stat st;
501 //
502 // Define admin file and check its existence
503 FileAdmin = infodir + AdminRef;
504 if (stat(FileAdmin.c_str(),&st) == -1) {
505 if (errno == ENOENT) {
506 PRINT("FileAdmin non existing: "<<FileAdmin.c_str());
507 } else {
508 PRINT("cannot stat FileAdmin (errno: "<<errno<<")");
509 }
510 FileAdmin = "";
511 if (UserPwd == 0 && !SysPwd) {
512 PRINT("no passwd info available - invalid ");
513 ErrF(erp,kPWErrInit,"could not find a valid password file");
514 return Parms;
515 }
516 }
517 if (FileAdmin.length() > 0) {
518 //
519 // Load server ID
520 PFAdmin.Init(FileAdmin.c_str(),0);
521 if (PFAdmin.IsValid()) {
522 //
523 // Init cache for admin file
524 if (cacheAdmin.Load(FileAdmin.c_str()) != 0) {
525 PRINT("problems init cache for file admin ");
526 ErrF(erp,kPWErrError,"initializing cache for file admin");
527 return Parms;
528 }
529 if (QTRACE(Authen)) { cacheAdmin.Dump(); }
530 XrdSutPFEntry *ent = cacheAdmin.Get(pfeRef, "+++SrvID");
531 if (ent)
532 {SrvID.insert(ent->buf1.buf, 0, ent->buf1.len);
533 pfeRef.UnLock();
534 }
535 ent = cacheAdmin.Get(pfeRef, "+++SrvEmail");
536 if (ent)
537 SrvEmail.insert(ent->buf1.buf, 0, ent->buf1.len);
538 // Default error message
539 DefError += SrvEmail;
540 pfeRef.UnLock();
541 }
542 DEBUG("server ID: "<<SrvID);
543 DEBUG("contact e-mail: "<<SrvEmail);
544 }
545 }
546 } else if (UserPwd == 0 && !SysPwd) {
547 PRINT("no passwd info available - invalid ");
548 ErrF(erp,kPWErrError,"could not find a valid password file");
549 return Parms;
550 }
551 //
552 // Init cache for user pwd information
553 if (UserPwd > 0 || SysPwd) {
554 if (cacheUser.Init(100) != 0) {
555 PRINT("problems init cache for user pwd info"
556 " - passwd files in user accounts will not be used");
557 UserPwd = 0;
558 }
559 }
560
561 //
562 // List of crypto modules
563 String cryptlist = opt.clist ? (const char *)(opt.clist) : DefCrypto;
564
565 //
566 // Load crypto modules
567 XrdSutPFEntry ent;
568 XrdCryptoFactory *cf = 0;
569 String clist = cryptlist;
570 if (clist.length()) {
571 String ncpt = "";
572 int from = 0;
573 while ((from = clist.tokenize(ncpt, from, '|')) != -1) {
574 if (ncpt.length() > 0) {
575 // Try loading
576 if ((cf = XrdCryptoFactory::GetCryptoFactory(ncpt.c_str()))) {
577 // Add it to the list
578 cryptID[ncrypt] = cf->ID();
579 cryptName[ncrypt].insert(cf->Name(),0,strlen(cf->Name())+1);
580 cf->SetTrace(trace);
581 // Ref cipher
582 String ptag("+++SrvPuk_");
583 ptag += cf->ID();
584 if (FileAdmin.length() > 0) {
585 // Acquire the privileges, if needed
586 XrdSysPrivGuard priv(pw->pw_uid, pw->pw_gid);
587 if (priv.Valid()) {
588 if (PFAdmin.ReadEntry(ptag.c_str(),ent) <= 0) {
589 PRINT("ref cipher for module "<<ncpt<<" missing: disable");
590 cryptlist.erase(ncpt);
591 } else {
592 XrdSutBucket bck;
593 bck.SetBuf(ent.buf1.buf,ent.buf1.len);
594 if (!(refcip[ncrypt] = cf->Cipher(&bck))) {
595 PRINT("ref cipher for module "<<ncpt<<
596 " cannot be instantiated : disable");
597 cryptlist.erase(ncpt);
598 } else {
599 ncrypt++;
600 if (ncrypt >= XrdCryptoMax) {
601 PRINT("max number of crypto modules ("
602 << XrdCryptoMax <<") reached ");
603 break;
604 }
605 }
606 }
607 }
608 }
609 } else {
610 PRINT("cannot instantiate crypto factory "<<ncpt);
611 }
612 }
613 }
614 }
615
616 //
617 // We need at least one valid crypto module
618 if (ncrypt <= 0) {
619 PRINT("could not find any valid crypto module");
620 ErrF(erp,kPWErrInit,"could not find any valid crypto module");
621 return Parms;
622 }
623
624 //
625 // users' pwd information
626 if (UserPwd > 0) {
627 FileUser = ("/" + UserRef);
628 if (opt.udir) {
629 FileUser.insert(opt.udir,0);
630 if (FileUser[0] != '/') FileUser.insert('/',0);
631 } else {
632 // Use default $(HOME)/.<Prefix>
633 FileUser.insert(Prefix,0);
634 FileUser.insert("/.",0);
635 }
636 //
637 // Crypt-hash file name, if requested
638 if (opt.cpass) {
639 UserPwd = 2;
640 FileCrypt = opt.cpass;
641 if (FileCrypt[0] != '/') FileCrypt.insert('/',0);
642 }
643 }
644
645 //
646 // Whether to save client creds
647 KeepCreds = (opt.keepcreds > -1) ? opt.keepcreds : KeepCreds;
648 if (KeepCreds > 0)
649 NOTIFY("Exporting client creds to internal buffer");
650
651 //
652 // Whether to export client creds to a file
653 FileExpCreds = (opt.expcreds) ? opt.expcreds : FileExpCreds;
654 if (FileExpCreds.length() > 0) {
655 // Export format
656 FmtExpCreds = opt.expfmt;
657 const char *efmts[4] = {"PFile", "hex", "raw", "raw/nokeyword"};
658 NOTIFY("Exporting client creds (fmt:"<<efmts[FmtExpCreds]<<") to files "<<FileExpCreds);
659 }
660
661 //
662 // Priority option field
663 String popt = "";
664 if (SysPwd) {
665 popt += "sys";
666 }
667
668 //
669 // Parms in the form: &P=pwd,c:<cryptomod>,v:<version>,id:<srvid>
670 Parms = new char[cryptlist.length()+3+12+SrvID.length()+5+popt.length()+3];
671 if (Parms) {
672 if (popt.length() > 0)
673 sprintf(Parms,"v:%d,id:%s,c:%s,po:%s",
674 Version,SrvID.c_str(),cryptlist.c_str(),popt.c_str());
675 else
676 sprintf(Parms,"v:%d,id:%s,c:%s",
677 Version,SrvID.c_str(),cryptlist.c_str());
678 } else {
679 PRINT("no system resources for 'Parms'");
680 ErrF(erp,kPWErrInit,"no system resources for 'Parms'");
681 }
682
683 // Some notification
684 NOTIFY("using FileAdmin: "<<FileAdmin);
685 NOTIFY("server ID: "<<SrvID);
686 NOTIFY("contact e-mail: "<<SrvEmail);
687 NOTIFY("auto-registration mode: "<<AutoReg);
688 NOTIFY("verify client mode: "<<VeriClnt);
689 NOTIFY("available crypto modules: "<<cryptlist);
690 if (UserPwd > 0) {
691 NOTIFY("using private pwd files: $(HOME)"<<FileUser);
692 if (UserPwd > 1) {
693 NOTIFY("using private crypt-hash files: $(HOME)"<<FileCrypt);
694 }
695 }
696 if (SysPwd) {
697 NOTIFY("using system pwd information");
698 }
699 if (KeepCreds) {
700 NOTIFY("client credentials will be kept");
701 }
702 }
703
704 //
705 // Client specific options
706 if (!Server) {
707 //
708 // Server verification level
709 VeriSrv = (opt.verisrv > -1) ? opt.verisrv : VeriSrv;
710 //
711 // Server puks file
712 FileSrvPuk = "";
713 if (opt.srvpuk) {
714 FileSrvPuk = opt.srvpuk;
715 if (XrdSutExpand(FileSrvPuk) != 0) {
716 PRINT("cannot expand "<<opt.srvpuk);
717 FileSrvPuk = "";
718 }
719 }
720 //
721 // If not defined, use default
722 if (FileSrvPuk.length() <= 0 && infodir.length() > 0)
723 FileSrvPuk = infodir + SrvPukRef;
724
725 if (FileSrvPuk.length() > 0) {
726 kXR_int32 openmode = 0;
727 struct stat st;
728 //
729 if (stat(FileSrvPuk.c_str(),&st) == -1) {
730 if (errno == ENOENT) {
731 PRINT("server public key file "<<FileSrvPuk<<" non existing: creating");
732 openmode = kPFEcreate;
733 // Make sure that the dir path exists
734 XrdOucString dir = FileSrvPuk;
735 dir.erase(dir.rfind('/')+1);
736 DEBUG("asserting dir: "<<dir);
737 if (XrdSutMkdir(dir.c_str(),0777) != 0) {
738 PRINT("cannot create dir for srvpuk(errno: "<<errno<<")");
739 ErrF(erp,kPWErrInit,"cannot create dir for server public key file- exit");
740 return Parms;
741 }
742 } else {
743 PRINT("cannot stat server public key file (errno: "<<errno<<")");
744 FileSrvPuk = "";
745 PRINT("server public key file invalid - exit");
746 ErrF(erp,kPWErrInit,"server public key file invalid - exit");
747 return Parms;
748 }
749 }
750 //
751 // Load server ID
752 PFSrvPuk.Init(FileSrvPuk.c_str(),openmode);
753 if (PFSrvPuk.IsValid()) {
754 //
755 // Init cache for server puk file
756 if (cacheSrvPuk.Load(FileSrvPuk.c_str()) != 0) {
757 PRINT("problems init cache for server public key file ");
758 ErrF(erp,kPWErrError,"initializing cache for server public key file ");
759 return Parms;
760 }
761 if (QTRACE(Authen)) { cacheSrvPuk.Dump(); }
762 } else {
763 PRINT("server public key file invalid ");
764 ErrF(erp,kPWErrInit,"server public key file invalid");
765 return Parms;
766 }
767 } else {
768 PRINT("server public key file undefined");
769 ErrF(erp,kPWErrInit,"server public key file undefined");
770 return Parms;
771 }
772
773 //
774 // Whether to search for autologin information
775 AutoLogin = (opt.alog > -1) ? opt.alog : AutoLogin;
776 NOTIFY("AutoLogin level: "<<AutoLogin);
777 //
778 // Max number of re-prompts (for inconsistent inputs)
779 MaxPrompts = (opt.maxprompts > -1) ? opt.maxprompts : MaxPrompts;
780 //
781 // Attach autologin file name, if requested
782 if (AutoLogin > 0) {
783 bool filefound = 0;
784 String fnrc(256);
785 if (opt.alogfile) {
786 fnrc = opt.alogfile;
787 if (XrdSutExpand(fnrc) != 0) {
788 PRINT("cannot expand "<<opt.alogfile);
789 fnrc = "";
790 }
791 }
792 //
793 // If file name not specified ...
794 if (fnrc.length() <= 0)
795 // use default
796 fnrc = infodir + NetRcRef;
797
798 if (fnrc.length() > 0) {
799 kXR_int32 openmode = 0;
800 struct stat st;
801 if (stat(fnrc.c_str(),&st) == -1) {
802 if (errno == ENOENT) {
803 PRINT("Autologin file "<<fnrc<<" non existing: creating");
804 openmode = kPFEcreate;
805 } else {
806 PRINT("cannot stat autologin file (errno: "<<errno<<")");
807 PRINT("switching off auto-login");
808 AutoLogin = 0;
809 }
810 }
811
812 if (AutoLogin > 0) {
813 // Attach to file
814 PFAlog.Init(fnrc.c_str(),openmode);
815 if (PFAlog.IsValid()) {
816 // Init cache for autologin file
817 if (cacheAlog.Load(fnrc.c_str()) == 0) {
818 if (QTRACE(Authen)) { cacheAlog.Dump(); }
819 filefound =1;
820 } else {
821 PRINT("problems init cache for autologin file");
822 }
823 } else {
824 PRINT("problems attaching-to / creating autologin file");
825 }
826 }
827 }
828 //
829 // Notify if not found
830 if (!filefound) {
831 NOTIFY("could not init properly autologin - switch off ");
832 AutoLogin = 0;
833 }
834 }
835 //
836 // Notify if not found
837 if (AutoLogin <= 0) {
838 // Init anyhow cache to cache information during session
839 if (cacheAlog.Init(100) != 0) {
840 PRINT("problems init cache for user temporary autolog");
841 }
842 }
843 // We are done
844 Parms = (char *)"";
845 }
846
847 // We are done
848 return Parms;
849}
#define TRACE_Debug
void XrdCryptoSetTrace(kXR_int32 trace)
#define cryptoTRACE_Notify
#define cryptoTRACE_Dump
#define cryptoTRACE_Debug
#define stat(a, b)
Definition XrdPosix.hh:101
static String Prefix
static String NetRcRef
XrdOucTrace * pwdTrace
static String SrvPukRef
static String UserRef
static String AdminRef
@ kPWErrInit
#define XrdCryptoMax
#define TRACE_Authen
int XrdSutExpand(XrdOucString &path)
Definition XrdSutAux.cc:360
int XrdSutMkdir(const char *dir, unsigned int mode, const char *opt)
Definition XrdSutAux.cc:487
const char * XrdSutHome()
Definition XrdSutAux.cc:459
void XrdSutSetTrace(kXR_int32 trace)
Definition XrdSutAux.cc:93
#define sutTRACE_Notify
Definition XrdSutAux.hh:100
#define sutTRACE_Debug
Definition XrdSutAux.hh:99
#define sutTRACE_Dump
Definition XrdSutAux.hh:98
#define kPFEcreate
#define TRACE_ALL
Definition XrdTrace.hh:35
virtual void SetTrace(kXR_int32 trace)
char * Name() const
virtual XrdCryptoCipher * Cipher(const char *t, int l=0)
static XrdCryptoFactory * GetCryptoFactory(const char *factoryname)
int erase(int start=0, int size=0)
int rfind(const char c, int start=STR_NPOS)
int tokenize(XrdOucString &tok, int from, char del=':')
int SetBuf(const char *nb=0, int ns=0)
kXR_int32 len
XrdSutPFBuf buf1

References AdminRef, pwdOptions::alog, pwdOptions::alogfile, pwdOptions::areg, XrdSutPFBuf::buf, XrdSutPFEntry::buf1, XrdOucString::c_str(), XrdCryptoFactory::Cipher(), pwdOptions::clist, pwdOptions::cpass, cryptoTRACE_Debug, cryptoTRACE_Dump, cryptoTRACE_Notify, DEBUG, pwdOptions::debug, pwdOptions::dir, XrdOucString::endswith(), EPNAME, XrdOucString::erase(), pwdOptions::expcreds, pwdOptions::expfmt, XrdCryptoFactory::GetCryptoFactory(), XrdCryptoFactory::ID(), pwdOptions::keepcreds, kPFEcreate, kPWErrError, kPWErrInit, XrdSutPFBuf::len, XrdOucString::length(), pwdOptions::lifecreds, pwdOptions::maxfailures, pwdOptions::maxprompts, pwdOptions::mode, XrdCryptoFactory::Name(), NetRcRef, NOTIFY, Prefix, PRINT, pwdTrace, QTRACE, XrdOucString::rfind(), XrdSutBucket::SetBuf(), XrdCryptoFactory::SetTrace(), pwdOptions::srvpuk, SrvPukRef, stat, sutTRACE_Debug, sutTRACE_Dump, sutTRACE_Notify, pwdOptions::syspwd, XrdOucString::tokenize(), TRACE_ALL, TRACE_Authen, TRACE_Debug, pwdOptions::udir, XrdSutPFCacheRef::UnLock(), pwdOptions::upwd, UserRef, XrdSysPrivGuard::Valid(), pwdOptions::vericlnt, pwdOptions::verisrv, Version, XrdCryptoMax, XrdCryptoSetTrace(), XrdSutExpand(), XrdSutHome(), XrdSutMkdir(), and XrdSutSetTrace().

Referenced by XrdSecProtocolpwdInit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PrintTimeStat()

void XrdSecProtocolpwd::PrintTimeStat ( )
static

References emsg(), ID, and XrdCryptoMax.

Here is the call graph for this function:

The documentation for this class was generated from the following files: