00001
00002
00003 const char *XrdSecpwdSrvAdminCVSID = "$Id: XrdSecpwdSrvAdmin.cc 30949 2009-11-02 16:37:58Z ganis $";
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include <stdio.h>
00050 #include <string.h>
00051 #include <stdlib.h>
00052 #include <sys/types.h>
00053 #include <sys/stat.h>
00054 #include <unistd.h>
00055 #include <sys/types.h>
00056 #include <fcntl.h>
00057 #include <errno.h>
00058 #include <pwd.h>
00059 #include <dirent.h>
00060
00061 #include <XrdOuc/XrdOucString.hh>
00062
00063 #include <XrdSut/XrdSutAux.hh>
00064 #include <XrdSut/XrdSutPFEntry.hh>
00065 #include <XrdSut/XrdSutPFile.hh>
00066 #include <XrdSut/XrdSutRndm.hh>
00067
00068 #include <XrdCrypto/XrdCryptoCipher.hh>
00069 #include <XrdCrypto/XrdCryptoFactory.hh>
00070
00071
00072
00073 enum kModes {
00074 kM_undef = 0,
00075 kM_admin = 1,
00076 kM_user,
00077 kM_netrc,
00078 kM_srvpuk,
00079 kM_help
00080 };
00081 const char *gModesStr[] = {
00082 "kM_undef",
00083 "kM_admin",
00084 "kM_user",
00085 "kM_netrc",
00086 "kM_srvpuk",
00087 "kM_help"
00088 };
00089 enum kActions {
00090 kA_undef = 0,
00091 kA_add = 1,
00092 kA_update,
00093 kA_read,
00094 kA_remove,
00095 kA_disable,
00096 kA_copy,
00097 kA_trim,
00098 kA_browse
00099 };
00100 const char *gActionsStr[] = {
00101 "kA_undef",
00102 "kA_add",
00103 "kA_update",
00104 "kA_read",
00105 "kA_remove",
00106 "kA_disable",
00107 "kA_copy",
00108 "kA_trim",
00109 "kA_browse"
00110 };
00111
00112
00113
00114 int DebugON = 1;
00115 XrdOucString DirRef = "~/.xrd/";
00116 XrdOucString AdminRef = "pwdadmin";
00117 XrdOucString UserRef = "pwduser";
00118 XrdOucString NetRcRef = "pwdnetrc";
00119 XrdOucString SrvPukRef= "pwdsrvpuk";
00120 XrdOucString GenPwdRef= "/genpwd/";
00121 XrdOucString GenPukRef= "/genpuk/";
00122 XrdOucString IDTag = "+++SrvID";
00123 XrdOucString EmailTag = "+++SrvEmail";
00124 XrdOucString HostTag = "+++SrvHost";
00125 XrdOucString PukTag = "+++SrvPuk";
00126 XrdOucString PwdFile = "";
00127 XrdOucString PukFile = "/home/ganis/.xrd/genpuk/puk.07May2005-0849";
00128 int Mode = kM_undef;
00129 int Action = kA_undef;
00130 int NoBackup = 1;
00131 XrdOucString NameTag = "";
00132 XrdOucString CopyTag = "";
00133 XrdOucString File = "";
00134 XrdOucString Path = "";
00135 XrdOucString Dir = "";
00136 XrdOucString SrvID = "";
00137 XrdOucString SrvName = "";
00138 XrdOucString Email = "";
00139 XrdOucString IterNum = "";
00140 bool Backup = 1;
00141 bool DontAsk = 0;
00142 bool Force = 0;
00143 bool Passwd = 1;
00144 bool Change = 1;
00145 bool Random = 0;
00146 bool SavePw = 1;
00147 bool SetID = 0;
00148 bool SetEmail = 0;
00149 bool SetHost = 0;
00150 bool Create = 0;
00151 bool Confirm = 1;
00152 bool Import = 0;
00153 bool Hash = 1;
00154 bool ChangePuk = 0;
00155 bool ChangePwd = 0;
00156 bool ExportPuk = 0;
00157
00158 #define NCRYPTMAX 10 // max number of crypto factories
00159
00160 XrdOucString DefCrypto = "ssl";
00161 XrdOucString CryptList = "";
00162 int ncrypt = 0;
00163 XrdOucString CryptMod[NCRYPTMAX] = {""};
00164 XrdCryptoCipher **RefCip = 0;
00165 XrdCryptoFactory **CF = 0;
00166 XrdCryptoKDFun_t KDFun = 0;
00167 XrdCryptoKDFunLen_t KDFunLen = 0;
00168
00169 void Menu(int opt = 0);
00170 int ParseArguments(int argc, char **argv);
00171 void ParseCrypto();
00172 bool CheckOption(XrdOucString opt, const char *ref, int &ival);
00173 bool AddPassword(XrdSutPFEntry &ent, XrdOucString salt,
00174 XrdOucString &ranpwd,
00175 bool random, bool checkpw, bool &newpw);
00176 bool AddPassword(XrdSutPFEntry &ent, bool &newpw, const char *pwd = 0);
00177 void SavePasswd(XrdOucString tag, XrdOucString pwd, bool onetime);
00178 bool ReadPasswd(XrdOucString &tag, XrdOucString &pwd, int &st);
00179 bool ReadPuk(int &npuk, XrdOucString *tpuk, XrdOucString *puk);
00180 int GeneratePuk();
00181 bool SavePuk();
00182 bool ReadPuk();
00183 bool ExpPuk(const char *puk = 0, bool read = 1);
00184 bool GetEntry(XrdSutPFile *ff, XrdOucString tag,
00185 XrdSutPFEntry &ent, bool &check);
00186 bool AskConfirm(const char *msg1, bool defact, const char *msg2 = 0);
00187 int LocateFactoryIndex(char *tag, int &id);
00188
00189 #define PRT(x) {cerr <<x <<endl;}
00190
00191 #define kMAXPWDATT 3
00192
00193 #define kMAXPUK 5
00194 int nHostPuk;
00195 XrdOucString TagHostPuk[kMAXPUK], HostPuk[kMAXPUK];
00196
00197 int main( int argc, char **argv )
00198 {
00199
00200
00201
00202 XrdSutPFEntry ent;
00203 XrdSutPFEntry *nent = 0;
00204 XrdOucString ans = "";
00205 XrdOucString email = "";
00206 XrdOucString uniqueid = "";
00207 XrdOucString tag = "";
00208 XrdOucString prompt = "Password: ";
00209 XrdOucString ranpwd = "";
00210 XrdOucString ImpPwd = "";
00211 XrdOucString salt = "";
00212 const char *pwdimp = 0;
00213 bool checkpwd = 0;
00214 bool newpw = 1;
00215 bool check = 0;
00216 int nr = 0, nm = 0;
00217 int i = 0;
00218 int entst = 0;
00219
00220
00221 if (ParseArguments(argc,argv)) {
00222 exit(0);
00223 }
00224 ParseCrypto();
00225
00226
00227 XrdSutSetTrace(sutTRACE_Debug);
00228
00229
00230 kXR_int32 openmode = (Create) ? kPFEcreate : 0;
00231 XrdSutPFile ff(File.c_str(), openmode);
00232 if (!ff.IsValid() && ff.LastError() == kPFErrNoFile) {
00233 prompt = "Create file ";
00234 prompt += File;
00235 if (DontAsk || AskConfirm(prompt.c_str(),0)) {
00236 if (Mode == kM_user || Mode == kM_srvpuk)
00237 ff.Init(File.c_str(), kPFEcreate, 0644);
00238 else
00239 ff.Init(File.c_str(), kPFEcreate);
00240 }
00241 if (!ff.IsValid())
00242 exit(1);
00243 if (Mode == kM_admin || Mode == kM_user) {
00244 if (SrvID.length() <= 0) {
00245 if (!DontAsk && AskConfirm("Would you like to enter a server ID? ",1)) {
00246 XrdSutGetLine(SrvID,"Enter ID (max 32 chars): ");
00247 if (SrvID.length() > 32)
00248 SrvID.erase(32);
00249 } else {
00250 PRT("Server ID will be generated randomly. It can be changed");
00251 PRT("at any time with 'add -srvID <ID>'.");
00252
00253
00254 XrdSutRndm::Init();
00255 XrdSutRndm::GetString(1,8,SrvID);
00256
00257
00258 struct passwd *pw = getpwuid(getuid());
00259 if (pw) {
00260 SrvID.insert(':',0);
00261 SrvID.insert(pw->pw_name,0);
00262 }
00263 }
00264 } else if (DontAsk) {
00265
00266 SetID = 0;
00267 }
00268 PRT("Server ID: " << SrvID);
00269 if (SrvID.length() > 0) {
00270
00271
00272 ent.SetName(IDTag.c_str());
00273 ent.status = kPFE_special;
00274 ent.cnt = 1;
00275 ent.buf1.SetBuf(SrvID.c_str(),SrvID.length()+1);
00276
00277
00278 ent.mtime = time(0);
00279 ff.WriteEntry(ent);
00280 PRT(" File successfully created with server ID set to: "
00281 <<SrvID.c_str());
00282 }
00283
00284 if (Mode == kM_admin) {
00285
00286 int ncf = GeneratePuk();
00287 if (ncf != ncrypt)
00288 PRT("// Could generate ref ciphers for all the factories");
00289
00290
00291 for ( i = 0; i < ncrypt; i++ ) {
00292 if (RefCip[i]) {
00293
00294
00295 tag = PukTag + '_';
00296 tag += CF[i]->ID();
00297
00298
00299 XrdSutBucket *bck = RefCip[i]->AsBucket();
00300 if (bck) {
00301
00302
00303 ent.SetName(tag.c_str());
00304 ent.status = kPFE_special;
00305 ent.cnt = 2;
00306 ent.buf1.SetBuf(bck->buffer,bck->size);
00307
00308
00309 ent.mtime = time(0);
00310 ff.WriteEntry(ent);
00311 PRT(" Server Puk saved for crypto: "<<CF[i]->Name());
00312 delete bck;
00313 bck = 0;
00314 }
00315 }
00316 }
00317
00318
00319 if (!SavePuk()) {
00320 PRT("// Problems with puk backup ");
00321 }
00322 }
00323 } else {
00324 PRT(" File successfully created ");
00325 }
00326 }
00327
00328
00329
00330 if (Mode == kM_admin) {
00331
00332
00333 ent.Reset();
00334 nm = ff.SearchEntries(PukTag.c_str(),0);
00335 if (nm) {
00336 int *ofs = new int[nm];
00337 ff.SearchEntries(PukTag.c_str(),0,ofs,nm);
00338 for ( i = 0; i < nm ; i++) {
00339 nr = ff.ReadEntry(ofs[i],ent);
00340 if (nr > 0) {
00341 XrdSutBucket bck;
00342 bck.SetBuf(ent.buf1.buf,ent.buf1.len);
00343
00344 int id = 0;
00345 int ii = LocateFactoryIndex(ent.name, id);
00346 if (ii < 0) {
00347 PRT("// Factory ID not found: corruption ?");
00348 exit(1);
00349 }
00350 if (!(RefCip[i] = CF[ii]->Cipher(&bck))) {
00351 PRT("// Could not instantiate cipher for factory "<<CF[ii]->Name());
00352 exit(1);
00353 }
00354 }
00355 }
00356 } else {
00357 PRT("// Ref puk ciphers not found: corruption ?");
00358 exit(1);
00359 }
00360
00361
00362 if (ff.ReadEntry(IDTag.c_str(),ent) <= 0 && !SetID) {
00363 PRT(" Unique ID missing: 'add -srvID' to set it");
00364 } else if (!SetID) {
00365 SrvID.insert(ent.buf1.buf,0,ent.buf1.len);
00366 }
00367
00368
00369 ent.Reset();
00370 if (ff.ReadEntry(IDTag.c_str(),ent) <= 0 && !SetID) {
00371 PRT(" Unique ID missing: 'add -srvID' to set it");
00372 } else if (!SetID) {
00373 SrvID.insert(ent.buf1.buf,0,ent.buf1.len);
00374 }
00375
00376
00377 ent.Reset();
00378 if (ff.ReadEntry(EmailTag.c_str(),ent) <= 0 && !SetEmail) {
00379 PRT(" Contact E-mail not set: 'add -email <email>' to set it");
00380 } else if (!SetEmail) {
00381 Email.insert(ent.buf1.buf,0,ent.buf1.len);
00382 }
00383
00384
00385 ent.Reset();
00386 if (ff.ReadEntry(HostTag.c_str(),ent) <= 0 && !SetHost) {
00387 PRT(" Local host name not set: 'add -host <host>' to set it");
00388 } else if (!SetHost) {
00389 SrvName.insert(ent.buf1.buf,0,ent.buf1.len);
00390 }
00391 }
00392
00393 switch (Action) {
00394 case kA_update:
00395
00396
00397 Force = 1;
00398 case kA_add:
00399
00400
00401
00402
00403
00404 if (Mode == kM_admin) {
00405
00406
00407 if (ExportPuk) {
00408 if (!ExpPuk()) {
00409 PRT("// Could not export public keys");
00410 }
00411
00412
00413 break;
00414 }
00415
00416
00417 ent.Reset();
00418 if (ChangePuk) {
00419 if (!DontAsk && !AskConfirm("Override server PUK?",0,0))
00420 break;
00421
00422
00423 if (Import && PukFile.length() > 0) {
00424 if (!ReadPuk()) {
00425 PRT("// Problem importing puks from "<<PukFile<<
00426 " - exit ");
00427 break;
00428 }
00429 } else {
00430
00431 if (GeneratePuk() != ncrypt) {
00432 PRT("// Could not generate ref ciphers for all the factories");
00433 break;
00434 }
00435 }
00436
00437
00438 if (!SavePuk()) {
00439 PRT("// Problems with puk backup ");
00440 }
00441
00442
00443 nm = ff.SearchEntries(PukTag.c_str(),0);
00444 if (nm) {
00445 PRT("// Found "<<nm<<" entries for tag '"<<PukTag.c_str()<<
00446 "' in file: "<<ff.Name());
00447
00448
00449 int *ofs = new int[nm];
00450
00451
00452 ff.SearchEntries(PukTag.c_str(),0,ofs,nm);
00453
00454
00455 for ( i = 0; i < nm ; i++) {
00456 nr = ff.ReadEntry(ofs[i],ent);
00457 if (nr > 0) {
00458
00459
00460 int id;
00461 int j = LocateFactoryIndex(ent.name,id);
00462 if (j < 0) break;
00463
00464 XrdSutBucket *bck = RefCip[j]->AsBucket();
00465 if (bck) {
00466
00467 if (ent.buf4.buf)
00468 delete[] ent.buf4.buf;
00469 ent.buf4.buf = ent.buf3.buf;
00470 ent.buf4.len = ent.buf3.len;
00471 ent.buf3.buf = ent.buf2.buf;
00472 ent.buf3.len = ent.buf2.len;
00473 ent.buf2.buf = ent.buf1.buf;
00474 ent.buf2.len = ent.buf1.len;
00475
00476 ent.buf1.SetBuf(bck->buffer,bck->size);
00477
00478
00479 ent.mtime = time(0);
00480 ff.WriteEntry(ent);
00481 PRT(" Server Puk updated for crypto: "<<CF[i]->Name());
00482 delete bck;
00483 bck = 0;
00484 }
00485
00486
00487 char stag[4];
00488 sprintf(stag,"*_%d",id);
00489 int nofs = ff.SearchEntries(stag,2);
00490 if (nofs > 0) {
00491 int *uofs = new int[nofs];
00492 ff.SearchEntries(stag,2,uofs,nofs);
00493 XrdSutPFEntry uent;
00494 int k = 0, nnr = 0;
00495 for (; k < nofs; k++) {
00496 uent.Reset();
00497 nnr = ff.ReadEntry(uofs[k],uent);
00498 if (nnr > 0 && !strstr(uent.name,PukTag.c_str())) {
00499 char c = 0;
00500 if (uent.buf4.buf) {
00501 c = *(uent.buf4.buf);
00502 c++;
00503 if (c > 4)
00504 c = 1;
00505 *(uent.buf4.buf) = c;
00506 } else {
00507 uent.buf4.buf = new char[1];
00508 uent.buf4.len = 1;
00509 *(uent.buf4.buf) = 2;
00510 }
00511
00512 uent.mtime = time(0);
00513 ff.WriteEntry(uent);
00514 }
00515 }
00516 }
00517 } else {
00518 PRT("// warning: problems reading entry: corruption?");
00519 break;
00520 }
00521 }
00522 } else {
00523 PRT("// WARNING: No entry for tag '"<<PukTag.c_str()<<
00524 "' found in file: "<<ff.Name()<<" : corruption? ");
00525 break;
00526 }
00527 }
00528
00529
00530 ent.Reset();
00531 if (SetID) {
00532 if (!GetEntry(&ff,IDTag,ent,check)) {
00533 if (!check || AskConfirm("Override server ID?",0,
00534 "This may cause inconveniences"
00535 " to clients")) {
00536
00537
00538 ent.SetName(IDTag.c_str());
00539 ent.status = kPFE_special;
00540 ent.cnt = 1;
00541 ent.buf1.SetBuf(SrvID.c_str(),SrvID.length()+1);
00542
00543
00544 ent.mtime = time(0);
00545 ff.WriteEntry(ent);
00546 PRT(" Server ID set to: "<<SrvID.c_str());
00547 }
00548 }
00549 }
00550
00551
00552 ent.Reset();
00553 if (SetEmail) {
00554 if (!GetEntry(&ff,EmailTag,ent,check)) {
00555 if (!check || AskConfirm("Override contact e-mail"
00556 " address?",0)) {
00557
00558
00559 ent.SetName(EmailTag.c_str());
00560 ent.status = kPFE_special;
00561 ent.cnt = 1;
00562 ent.buf1.SetBuf(Email.c_str(),Email.length()+1);
00563
00564
00565 ent.mtime = time(0);
00566 ff.WriteEntry(ent);
00567 PRT(" Contact e-mail set to: "<<Email.c_str());
00568 }
00569 }
00570 }
00571
00572
00573 ent.Reset();
00574 if (SetHost) {
00575 if (!GetEntry(&ff,HostTag,ent,check)) {
00576 if (!check || AskConfirm("Override server host name?",0)) {
00577
00578
00579 ent.SetName(HostTag.c_str());
00580 ent.status = kPFE_special;
00581 ent.cnt = 1;
00582 ent.buf1.SetBuf(SrvName.c_str(),SrvName.length()+1);
00583
00584
00585 ent.mtime = time(0);
00586 ff.WriteEntry(ent);
00587 PRT(" Server host name set to: "<<SrvName.c_str());
00588 }
00589 }
00590 }
00591
00592 }
00593
00594
00595 if (Mode == kM_srvpuk) {
00596 if (!Import) {
00597 PRT("// Updating the server puk file requires a file with "<<
00598 "the keys received by the server administrator:");
00599 PRT("// rerun with option '-import <file_with_keys>' ");
00600 break;
00601 }
00602 if (!ReadPuk(nHostPuk,TagHostPuk,HostPuk))
00603 break;
00604
00605
00606 for (i = 0; i < nHostPuk; i++) {
00607
00608 ent.Reset();
00609 if (GetEntry(&ff,TagHostPuk[i],ent,check)) {
00610 break;
00611 }
00612
00613 ent.buf1.SetBuf(HostPuk[i].c_str(),HostPuk[i].length()+1);
00614
00615 ent.mtime = time(0);
00616 ff.WriteEntry(ent);
00617 if (check) {
00618 PRT("// Server puk "<<TagHostPuk[i]<<" updated");
00619 } else {
00620 PRT("// Server puk "<<TagHostPuk[i]<<" added");
00621 }
00622 }
00623
00624
00625 ff.Browse();
00626
00627
00628 break;
00629 }
00630
00631
00632 if (Mode == kM_netrc) {
00633 if (Import) {
00634 if (!ReadPasswd(NameTag,ImpPwd,entst))
00635 break;
00636 pwdimp = ImpPwd.c_str();;
00637 }
00638
00639
00640 if (!Hash) {
00641
00642 ent.Reset();
00643 if (GetEntry(&ff,NameTag,ent,checkpwd)) {
00644 break;
00645 }
00646
00647 ent.status = entst;
00648 ent.cnt = 0;
00649
00650
00651 if (!AddPassword(ent, newpw, pwdimp)) {
00652 PRT("Error creating new password: "<<gModesStr[Mode]);
00653 break;
00654 }
00655
00656
00657 ent.mtime = time(0);
00658 ff.WriteEntry(ent);
00659 PRT(" Entry for tag '"<<NameTag<<
00660 "' created / updated");
00661
00662 break;
00663 }
00664 }
00665
00666
00667 if (!NameTag.length()) break;
00668
00669
00670 prompt = "Adding/Updating entry for tag: ";
00671 prompt += NameTag;
00672 if (!DontAsk && !AskConfirm("Do you want to continue?",0,prompt.c_str()))
00673 break;
00674
00675
00676 KDFun = 0;
00677 KDFunLen = 0;
00678 newpw = 1;
00679
00680
00681 if (Mode != kM_netrc) {
00682 XrdSutRndm::Init();
00683 XrdSutRndm::GetString(3,8,salt);
00684 if (IterNum.length() > 0) {
00685
00686 salt.insert(IterNum,0);
00687 }
00688 }
00689
00690 for ( i = 0; i < ncrypt; i++ ) {
00691
00692 CF[i] = XrdCryptoFactory::GetCryptoFactory(CryptMod[i].c_str());
00693 if (!CF[i]) {
00694 PRT("Hook for crypto factory undefined: "<<CryptMod[i].c_str());
00695 break;
00696 }
00697
00698
00699 KDFun = CF[i]->KDFun();
00700 KDFunLen = CF[i]->KDFunLen();
00701 if (!KDFun || !KDFunLen) {
00702 PRT("Error resolving one-way hash functions ");
00703 break;
00704 }
00705
00706
00707 tag = NameTag + '_';
00708 tag += CF[i]->ID();
00709
00710 ent.Reset();
00711 if (GetEntry(&ff,tag,ent,checkpwd)) {
00712 break;
00713 }
00714 if (Mode == kM_netrc) {
00715
00716 if (ChangePwd) {
00717 if (!checkpwd)
00718 break;
00719 else
00720
00721 ent.status = kPFE_onetime;
00722 } else {
00723
00724 if (pwdimp)
00725 ent.status = entst;
00726 else
00727 ent.status = kPFE_ok;
00728 ent.cnt = 0;
00729
00730
00731 if (!AddPassword(ent, newpw, pwdimp)) {
00732 PRT("Error creating new password: "<<gModesStr[Mode]);
00733 break;
00734 }
00735 }
00736 } else {
00737
00738 ent.cnt = 0;
00739 if (Passwd) {
00740
00741 ent.status = Change ? kPFE_onetime : kPFE_ok;
00742
00743
00744 if (!AddPassword(ent, salt, ranpwd, Random, checkpwd, newpw)) {
00745 PRT("Error creating new password: "<<gModesStr[Mode]);
00746 break;
00747 }
00748 } else {
00749 ent.buf1.SetBuf();
00750 ent.buf2.SetBuf();
00751 ent.buf3.SetBuf();
00752 ent.buf4.SetBuf();
00753
00754 ent.status = kPFE_allowed;
00755 }
00756 }
00757
00758
00759 ent.mtime = time(0);
00760 ff.WriteEntry(ent);
00761 PRT(" Entry for tag '"<<tag.c_str()<<
00762 "' created / updated");
00763 }
00764
00765
00766 if (SavePw)
00767 SavePasswd(NameTag, ranpwd, Change);
00768
00769
00770 ff.Browse();
00771 break;
00772
00773 case kA_read:
00774
00775
00776 nm = ff.SearchEntries(NameTag.c_str(),0);
00777 PRT("//-----------------------------------------------------"
00778 "--------------------//");
00779 PRT("//");
00780 if (nm) {
00781 PRT("// Found "<<nm<<" entries for tag '"<<NameTag.c_str()<<
00782 "' in file: "<<ff.Name());
00783
00784
00785 int *ofs = new int[nm];
00786
00787
00788 ff.SearchEntries(NameTag.c_str(),0,ofs,nm);
00789
00790
00791 for ( i = 0; i < nm ; i++) {
00792 nr = ff.ReadEntry(ofs[i],ent);
00793 if (nr > 0) {
00794 PRT("// #:"<<i+1<<" "<<ent.AsString());
00795 } else {
00796 PRT("// Entry for ofs "<<ofs[i]<<
00797 " not found in file: "<<ff.Name());
00798 }
00799 }
00800 } else {
00801 PRT("// No entry for tag '"<<NameTag.c_str()<<
00802 "' found in file: "<<ff.Name());
00803 }
00804 PRT("//");
00805 PRT("//-----------------------------------------------------"
00806 "--------------------//");
00807 break;
00808
00809 case kA_remove:
00810
00811
00812 prompt = "Removing entry for tag: ";
00813 prompt += NameTag;
00814 if (!DontAsk && !AskConfirm("Do you want to continue?",0,prompt.c_str()))
00815 break;
00816
00817
00818 nm = ff.SearchEntries(NameTag.c_str(),0);
00819 PRT("//-----------------------------------------------------"
00820 "--------------------//");
00821 PRT("//");
00822 if (nm) {
00823 PRT("// Found "<<nm<<" entries for tag '"<<NameTag.c_str()<<
00824 "' in file: "<<ff.Name());
00825
00826
00827 int *ofs = new int[nm];
00828
00829
00830 ff.SearchEntries(NameTag.c_str(),0,ofs,nm);
00831
00832
00833 for ( i = 0; i < nm ; i++) {
00834 if (ff.RemoveEntry(ofs[i]) == 0) {
00835 PRT("// Entry for tag '"<<NameTag.c_str()<<
00836 "' removed from file: "<<ff.Name());
00837 } else {
00838 PRT("// Entry for tag '"<<NameTag.c_str()<<
00839 "' not found in file: "<<ff.Name());
00840 }
00841 }
00842 } else {
00843 PRT("// No entry for tag '"<<NameTag.c_str()<<
00844 "' found in file: "<<ff.Name());
00845 }
00846 PRT("//");
00847 PRT("//-----------------------------------------------------"
00848 "--------------------//");
00849 break;
00850
00851 case kA_disable:
00852
00853
00854 prompt = "Disabling entry for tag: ";
00855 prompt += NameTag;
00856 if (!DontAsk && !AskConfirm("Do you want to continue?",0,prompt.c_str()))
00857 break;
00858
00859
00860 nm = ff.SearchEntries(NameTag.c_str(),0);
00861 PRT("//-----------------------------------------------------"
00862 "--------------------//");
00863 PRT("//");
00864 if (nm) {
00865 PRT("// Found "<<nm<<" entries for tag '"<<NameTag.c_str()<<
00866 "' in file: "<<ff.Name());
00867
00868
00869 int *ofs = new int[nm];
00870
00871
00872 ff.SearchEntries(NameTag.c_str(),0,ofs,nm);
00873
00874
00875 for ( i = 0; i < nm ; i++) {
00876 nr = ff.ReadEntry(ofs[i],ent);
00877 if (nr > 0) {
00878
00879 ent.status = kPFE_disabled;
00880 ent.cnt = 0;
00881 ent.buf1.SetBuf();
00882 ent.buf2.SetBuf();
00883 ent.buf3.SetBuf();
00884 ent.buf4.SetBuf();
00885
00886 ent.mtime = time(0);
00887 ff.WriteEntry(ent);
00888 PRT("// Entry for tag '"<<ent.name<<
00889 "' disabled");
00890 } else {
00891 PRT("// Entry for ofs "<<ofs[i]<<
00892 " not found in file: "<<ff.Name());
00893 }
00894 }
00895 } else {
00896 PRT("// No entry for tag '"<<NameTag.c_str()<<
00897 "' found in file: "<<ff.Name());
00898 }
00899 PRT("//");
00900 PRT("//-----------------------------------------------------"
00901 "--------------------//");
00902 break;
00903
00904 case kA_copy:
00905
00906
00907 prompt = "Copying entry for tag: ";
00908 prompt += NameTag;
00909 prompt += " into tag: ";
00910 prompt += CopyTag;
00911 if (!DontAsk && !AskConfirm("Do you want to continue?",0,prompt.c_str()))
00912 break;
00913
00914
00915 if (ff.ReadEntry(NameTag.c_str(),ent) <= 0) {
00916 PRT("Entry to copy not found missing");
00917 break;
00918 }
00919
00920
00921 nent = new XrdSutPFEntry(ent);
00922 PRT("//-----------------------------------------------------"
00923 "--------------------//");
00924 PRT("//");
00925 if (nent) {
00926 nent->SetName(CopyTag.c_str());
00927
00928
00929 nent->mtime = time(0);
00930 ff.WriteEntry(*nent);
00931 PRT("// Entry for tag '"<<nent->name<<
00932 "' created");
00933 delete nent;
00934 } else {
00935 PRT("// Cannot create new entry: out of memory");
00936 break;
00937 }
00938 PRT("//");
00939 PRT("//-----------------------------------------------------"
00940 "--------------------//");
00941 break;
00942
00943 case kA_trim:
00944
00945
00946 ff.Trim();
00947
00948 case kA_browse:
00949 default:
00950
00951
00952 ff.Browse();
00953 }
00954
00955 exit(0);
00956 }
00957
00958
00959 void Menu(int opt)
00960 {
00961
00962
00963
00964
00965
00966
00967 if (opt == 0) {
00968 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
00969 PRT("+ +");
00970 PRT("+ x r d p w d a d m i n +");
00971 PRT("+ +");
00972 PRT("+ Administration of pwd files +");
00973 }
00974
00975
00976 if (opt <= 1) {
00977 PRT("+ +");
00978 PRT("+ Syntax: +");
00979 PRT("+ +");
00980 PRT("+ xrdpwdadmin [-h] [-m <mode>] [options] +");
00981 PRT("+ +");
00982 PRT("+ -h display this menu +");
00983 PRT("+ +");
00984 PRT("+ -m choose mode (admin, user, netrc, srvpuk) [admin] +");
00985 PRT("+ +");
00986 PRT("+ admin: +");
00987 PRT("+ create / modify the main file used by servers +");
00988 PRT("+ started from this account to validate clients +");
00989 PRT("+ credentials. Default location and name: +");
00990 PRT("+ $(HOME)/.xrd/pwdadmin +");
00991 PRT("+ +");
00992 PRT("+ NB: file must readable and writable by owner +");
00993 PRT("+ only e.g. 0600 +");
00994 PRT("+ +");
00995 PRT("+ user: +");
00996 PRT("+ create / modify local file used by servers +");
00997 PRT("+ to validate this user credentials. +");
00998 PRT("+ Default location and name: +");
00999 PRT("+ $(HOME)/.xrd/pwduser +");
01000 PRT("+ +");
01001 PRT("+ NB: the file must be copied on the server machine +");
01002 PRT("+ if produced elsewhere; file must be writable +");
01003 PRT("+ by the owner only, e.g. 0644 +");
01004 PRT("+ +");
01005 PRT("+ netrc: +");
01006 PRT("+ create / modify local autologin file +");
01007 PRT("+ Default location and name: +");
01008 PRT("+ $(HOME)/.xrd/pwdnetrc +");
01009 PRT("+ +");
01010 PRT("+ NB: file must readable and writable by owner +");
01011 PRT("+ only e.g. 0600 +");
01012 PRT("+ +");
01013 PRT("+ srvpuk: +");
01014 PRT("+ create / modify local file with known server +");
01015 PRT("+ public cipher initializers. +");
01016 PRT("+ Default location and name: +");
01017 PRT("+ $(HOME)/.xrd/pwdsrvpuk +");
01018 PRT("+ +");
01019 PRT("+ NB: file must be writable by the owner only +");
01020 PRT("+ e.g. 0644 +");
01021 }
01022
01023
01024 if (opt <= 2) {
01025 PRT("+ +");
01026 PRT("+ Options: +");
01027 PRT("+ +");
01028 PRT("+ add <name> [-[no]force] [-[no]random] [-[no]savepw] +");
01029 PRT("+ add entry with tag <name>; the application prompts +");
01030 PRT("+ for the password +");
01031 PRT("+ +");
01032 PRT("+ add <name> -import <pwd_file> +");
01033 PRT("+ add entry with tag <name> importing the pwd from +");
01034 PRT("+ the file send by the server administrator +");
01035 PRT("+ [netrc only] +");
01036 PRT("+ +");
01037 PRT("+ add -import <srvkey_file> +");
01038 PRT("+ add new server key importing the key from +");
01039 PRT("+ the file send by the server administrator +");
01040 PRT("+ [srvpuk only] +");
01041 PRT("+ +");
01042 PRT("+ update <name> [options] +");
01043 PRT("+ equivalent to 'add -force' +");
01044 PRT("+ +");
01045 PRT("+ read <name> +");
01046 PRT("+ list some information of entry associated with tag +");
01047 PRT("+ <name> (status, count, date of last change, buffer +");
01048 PRT("+ lengths); buffer contents not listed +");
01049 PRT("+ +");
01050 PRT("+ remove <name> +");
01051 PRT("+ Make entry associated with tag <name> inactive +");
01052 PRT("+ (Spce is recovered during next trim operation) +");
01053 PRT("+ +");
01054 PRT("+ copy <name> <newname> +");
01055 PRT("+ Create new entry with tag <newname> and content of +");
01056 PRT("+ existing entry with tag <name> +");
01057 PRT("+ +");
01058 PRT("+ trim [-nobackup] +");
01059 PRT("+ Trim the file content eliminating all the inactive +");
01060 PRT("+ entries; a backup is created in <file>.bak unless +");
01061 PRT("+ the option '-nobackup' is specified +");
01062 PRT("+ +");
01063 PRT("+ browse +");
01064 PRT("+ list a table about the file content +");
01065 }
01066
01067
01068 if (opt <= 3) {
01069 PRT("+ +");
01070 PRT("+ -dontask +");
01071 PRT("+ do not prompt for questions: when in doubt use +");
01072 PRT("+ defaults or fail +");
01073 PRT("+ [default: ask] +");
01074 PRT("+ -force +");
01075 PRT("+ overwrite entry if it exists already +");
01076 PRT("+ [default: do not overwrite] +");
01077 PRT("+ -[no]change +");
01078 PRT("+ do [not] require user to change info on first use +");
01079 PRT("+ [default: admin: change / user: no change +");
01080 PRT("+ -crypto [-]<crypt1>|[-]<crypt2>|... +");
01081 PRT("+ create information for the given crypto modules +");
01082 PRT("+ ('|' separated list) in addition to default ones +");
01083 PRT("+ (normally ssl and local); use '-' in front to avoid +");
01084 PRT("+ avoid creating a entry for a module; one entry is +");
01085 PRT("+ for each module with effective tag of the form +");
01086 PRT("+ name_<cryptoID> [default list: ssl] +");
01087 PRT("+ [default: create backup] +");
01088 }
01089
01090
01091 PRT("+ +");
01092 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01093 }
01094
01095 int ParseArguments(int argc, char **argv)
01096 {
01097
01098 bool changeset = 0;
01099 bool randomset = 0;
01100 bool savepwset = 0;
01101 bool randomid = 0;
01102
01103
01104 if (argc < 0 || !argv[0]) {
01105 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01106 PRT("+ Insufficient number or arguments! +");
01107 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01108
01109 Menu(0);
01110 return 1;
01111 }
01112 --argc;
01113 ++argv;
01114
01115
01116
01117 while ((argc >= 0) && (*argv)) {
01118
01119 XrdOucString opt = "";
01120 int ival = -1;
01121 if(*(argv)[0] == '-') {
01122
01123 opt = *argv;
01124 opt.erase("-");
01125 if (CheckOption(opt,"m",ival)) {
01126 if (Mode != kM_undef) {
01127 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01128 PRT("+ Only one valid '-m' option allowed: ignoring +");
01129 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01130 --argc;
01131 ++argv;
01132 if (argc >= 0 && (*argv && *(argv)[0] == '-')) {
01133 argc++;
01134 argv--;
01135 }
01136 }
01137 --argc;
01138 ++argv;
01139 if (argc >= 0 && (*argv && *(argv)[0] != '-')) {
01140 XrdOucString mode = *argv;
01141 if (CheckOption(mode,"admin",ival)) {
01142 Mode = kM_admin;
01143 } else if (CheckOption(mode,"user",ival)) {
01144 Mode = kM_user;
01145 } else if (CheckOption(mode,"netrc",ival)) {
01146 Mode = kM_netrc;
01147 } else if (CheckOption(mode,"srvpuk",ival)) {
01148 Mode = kM_srvpuk;
01149 } else if (CheckOption(mode,"help",ival)) {
01150 Mode = kM_help;
01151 } else {
01152 PRT("++++++++++++++++++++++++++++++++++++++"
01153 "++++++++++++++++++++++");
01154 PRT("+ Ignoring unrecognized more: "<<mode.c_str());
01155 PRT("++++++++++++++++++++++++++++++++++++++"
01156 "++++++++++++++++++++++");
01157 }
01158 } else {
01159 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01160 PRT("+ Option '-m' requires {admin,user,netrc,srvpuk}: ignoring +");
01161 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01162 argc++;
01163 argv--;
01164 }
01165 } else if (CheckOption(opt,"h",ival) ||
01166 CheckOption(opt,"help",ival) ||
01167 CheckOption(opt,"menu",ival)) {
01168 Mode = kM_help;
01169 } else if (CheckOption(opt,"f",ival)) {
01170 --argc;
01171 ++argv;
01172 if (argc >= 0 && (*argv && *(argv)[0] != '-')) {
01173 Path = *argv;
01174 } else {
01175 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01176 PRT("+ Option '-f' requires a file or directory name: ignoring +");
01177 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01178 argc++;
01179 argv--;
01180 }
01181 } else if (CheckOption(opt,"dontask",ival)) {
01182 DontAsk = ival;
01183 } else if (CheckOption(opt,"force",ival)) {
01184 Force = ival;
01185 } else if (CheckOption(opt,"change",ival)) {
01186 Change = ival;
01187 changeset = 1;
01188 } else if (CheckOption(opt,"passwd",ival)) {
01189 Passwd = ival;
01190 } else if (CheckOption(opt,"backup",ival)) {
01191 Backup = ival;
01192 } else if (CheckOption(opt,"random",ival)) {
01193 Random = ival;
01194 randomset = 1;
01195 } else if (CheckOption(opt,"savepw",ival)) {
01196 SavePw = ival;
01197 savepwset = 1;
01198 } else if (CheckOption(opt,"confirm",ival)) {
01199 Confirm = ival;
01200 } else if (CheckOption(opt,"create",ival)) {
01201 Create = ival;
01202 } else if (CheckOption(opt,"hash",ival)) {
01203 Hash = ival;
01204 } else if (CheckOption(opt,"changepuk",ival)) {
01205 ChangePuk = ival;
01206 } else if (CheckOption(opt,"changepwd",ival)) {
01207 ChangePwd = ival;
01208 } else if (CheckOption(opt,"exportpuk",ival)) {
01209 ExportPuk = ival;
01210 } else if (CheckOption(opt,"iternum",ival)) {
01211 --argc;
01212 ++argv;
01213 if (argc >= 0 && (*argv && *(argv)[0] != '-')) {
01214 int iter = strtol(*argv,0,10);
01215 if (iter > 0 && errno != ERANGE) {
01216 IterNum = "$$";
01217 IterNum += *argv;
01218 IterNum += "$";
01219 } else {
01220 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01221 PRT("+ Option '-iternum' requires a positive number: ignoring +");
01222 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01223 argc++;
01224 argv--;
01225 }
01226 } else {
01227 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01228 PRT("+ Option '-iternum' requires a positive number: ignoring +");
01229 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01230 argc++;
01231 argv--;
01232 }
01233 } else if (CheckOption(opt,"crypto",ival)) {
01234 --argc;
01235 ++argv;
01236 if (argc >= 0 && (*argv && *(argv)[0] != '-')) {
01237 CryptList = *argv;
01238 } else {
01239 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01240 PRT("+ Option '-crypto' requires a list of modules: ignoring +");
01241 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01242 argc++;
01243 argv--;
01244 }
01245 } else if (CheckOption(opt,"import",ival)) {
01246 --argc;
01247 ++argv;
01248 if (argc >= 0 && (*argv && *(argv)[0] != '-')) {
01249 if (Mode == kM_netrc) {
01250 PwdFile = *argv;
01251 } else {
01252 PukFile = *argv;
01253 }
01254 Import = 1;
01255 } else {
01256 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01257 PRT("+ Option '-import' requires a file name: ignoring +");
01258 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01259 argc++;
01260 argv--;
01261 }
01262 } else if (CheckOption(opt,"srvID",ival)) {
01263 --argc;
01264 ++argv;
01265 SetID = 1;
01266 if (argc >= 0 && (*argv && *(argv)[0] != '-')) {
01267 SrvID = *argv;
01268 } else {
01269 SrvID = "";
01270 randomid = 1;
01271 argc++;
01272 argv--;
01273 }
01274 } else if (CheckOption(opt,"email",ival)) {
01275 --argc;
01276 ++argv;
01277 if (argc >= 0 && (*argv && *(argv)[0] != '-')) {
01278 Email = *argv;
01279 SetEmail = 1;
01280 } else {
01281 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01282 PRT("+ Option '-email' requires an email string: ignoring +");
01283 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01284 argc++;
01285 argv--;
01286 }
01287 } else if (CheckOption(opt,"host",ival)) {
01288 --argc;
01289 ++argv;
01290 if (argc >= 0 && (*argv && *(argv)[0] != '-')) {
01291 SrvName = *argv;
01292 SetHost = 1;
01293 } else {
01294 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01295 PRT("+ Option '-host' requires the local host name: ignoring +");
01296 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01297 argc++;
01298 argv--;
01299 }
01300 } else {
01301 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01302 PRT("+ Ignoring unrecognized option: "<<*argv);
01303 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01304 }
01305
01306 } else {
01307
01308
01309 opt = *argv;
01310 int iad = -1, iup = -1, ird = -1, irm = -1, idi = -1, icp = -1;
01311 if (CheckOption(opt,"add",iad) || CheckOption(opt,"update",iup) ||
01312 CheckOption(opt,"read",ird) || CheckOption(opt,"remove",irm) ||
01313 CheckOption(opt,"disable",idi) || CheckOption(opt,"copy",icp)) {
01314 Action = (Action == kA_undef && iad == 1) ? kA_add : Action;
01315 Action = (Action == kA_undef && iup == 1) ? kA_update : Action;
01316 Action = (Action == kA_undef && ird == 1) ? kA_read : Action;
01317 Action = (Action == kA_undef && irm == 1) ? kA_remove : Action;
01318 Action = (Action == kA_undef && idi == 1) ? kA_disable : Action;
01319 Action = (Action == kA_undef && icp == 1) ? kA_copy : Action;
01320 --argc;
01321 ++argv;
01322 if (argc >= 0 && (*argv && *(argv)[0] != '-')) {
01323 NameTag = *argv;
01324 if (icp == 1) {
01325 --argc;
01326 ++argv;
01327 if (argc >= 0 && (*argv && *(argv)[0] != '-')) {
01328 CopyTag = *argv;
01329 } else {
01330 PRT("+++++++++++++++++++++++++++++++++++++++++"
01331 "+++++++++++++++++++");
01332 PRT("+ 'copy': missing destination tag: ignoring"
01333 " +");
01334 PRT("+++++++++++++++++++++++++++++++++++++++++"
01335 "+++++++++++++++++++");
01336 CopyTag = "";
01337 argc++;
01338 argv--;
01339 }
01340 }
01341 } else {
01342 NameTag = "";
01343 argc++;
01344 argv--;
01345 }
01346 } else if (CheckOption(opt,"trim",ival)) {
01347 Action = kA_trim;
01348 } else if (CheckOption(opt,"browse",ival)) {
01349 Action = kA_browse;
01350 } else {
01351 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01352 PRT("+ Ignoring unrecognized keyword action: "<<opt.c_str());
01353 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01354 }
01355 }
01356 --argc;
01357 ++argv;
01358 }
01359
01360
01361
01362 Mode = (Mode == 0) ? kM_admin : Mode;
01363
01364
01365
01366 if (Mode == kM_help) {
01367
01368 Menu(0);
01369 return 1;
01370 }
01371
01372
01373
01374 bool special = SetID || SetEmail || SetHost || ChangePuk || ExportPuk;
01375 if (Action == kA_add || Action == kA_update ||
01376 Action == kA_read || Action == kA_remove) {
01377 if (!special && !NameTag.length() &&!Import) {
01378 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01379 PRT("+ Specified action requires a tag: "<<
01380 gActionsStr[Action]);
01381 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01382 Menu(2);
01383 return 1;
01384 }
01385 }
01386
01387
01388
01389
01390
01391 if (Mode == kM_admin && SetID) {
01392 if (randomid) {
01393
01394 XrdSutRndm::Init();
01395 XrdSutRndm::GetString(1,8,SrvID);
01396
01397 struct passwd *pw = getpwuid(getuid());
01398 if (pw) {
01399 SrvID.insert(':',0);
01400 SrvID.insert(pw->pw_name,0);
01401 } else {
01402 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01403 PRT("+ WARNING: could not get local user info for srv ID +");
01404 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01405 }
01406 } else {
01407 if (SrvID.length() > 32) {
01408 SrvID.erase(32);
01409 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01410 PRT("+ WARNING: srv ID too long: truncating to 32 chars: "
01411 <<SrvID.c_str());
01412 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01413 }
01414 }
01415 }
01416
01417
01418
01419
01420 if (IterNum.length() > 0 && (Mode != kM_admin && Mode != kM_user)) {
01421 IterNum = "";
01422 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01423 PRT("+ WARNING: ignore iter num change request (not admin/user) +");
01424 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01425 }
01426
01427
01428
01429 if (ChangePwd && Mode != kM_netrc) {
01430 ChangePwd = 0;
01431 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01432 PRT("+ WARNING: ignore password change request (not netrc) +");
01433 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01434 }
01435
01436
01437
01438
01439
01440 if (Mode == kM_user && NameTag.length()) {
01441 struct passwd *pw = getpwuid(getuid());
01442 if (pw) {
01443 XrdOucString locusr = pw->pw_name;
01444 if (NameTag != locusr) {
01445 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01446 PRT("+ WARNING: name tag does not match local user name: ");
01447 PRT("+ "<<NameTag.c_str()<<" "<<locusr.c_str());
01448 PRT("+ Some servers may ignore this entry ");
01449 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01450 if (Action == kA_add)
01451 Confirm = 1;
01452 }
01453 }
01454 }
01455
01456
01457
01458 Action = (Action == kA_undef && special) ? kA_add : Action;
01459 Action = (Action == kA_undef) ? kA_browse : Action;
01460
01461
01462
01463 if (Mode == kM_admin) {
01464 Change = (changeset) ? Change : 1;
01465 Random = (randomset) ? Random : 1;
01466 SavePw = (savepwset) ? SavePw : 1;
01467 } else {
01468 Change = (changeset) ? Change : 0;
01469 Random = (randomset) ? Random : 0;
01470 SavePw = (savepwset) ? SavePw : 0;
01471 }
01472
01473
01474
01475 Create = (Action == kA_add || Action == kA_update) ? Create : 0;
01476
01477
01478
01479 if (Path.length()) {
01480
01481
01482 XrdSutExpand(Path);
01483
01484 struct stat st;
01485 if (stat(Path.c_str(),&st) == 0) {
01486 if (S_ISDIR(st.st_mode)) {
01487
01488 Dir = Path;
01489 } else {
01490
01491 File = Path;
01492 }
01493 } else {
01494 if (errno == ENOENT) {
01495
01496 File = Path;
01497 } else {
01498
01499 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01500 PRT("+ Cannot access requested path: "<<Path.c_str());
01501 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01502 return 1;
01503 }
01504 }
01505 }
01506
01507
01508 if (!File.length()) {
01509 if (!Dir.length())
01510 Dir = DirRef;
01511
01512 XrdSutExpand(Dir);
01513 File = Dir;
01514
01515 if (XrdSutMkdir(File.c_str(),0777) != 0) {
01516 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01517 PRT("+ Cannot create requested path: "<<File.c_str());
01518 PRT("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
01519 return 1;
01520 }
01521
01522 if (Mode == kM_admin) {
01523 File += AdminRef;
01524 } else if (Mode == kM_user) {
01525 File += UserRef;
01526 } else if (Mode == kM_netrc) {
01527 File += NetRcRef;
01528 } else if (Mode == kM_srvpuk) {
01529 File += SrvPukRef;
01530 }
01531 }
01532
01533 return 0;
01534 }
01535
01536 void ParseCrypto()
01537 {
01538
01539
01540
01541 if (CryptList == "")
01542 CryptList = DefCrypto;
01543
01544
01545
01546 int from = 0;
01547 while ((from = CryptList.tokenize(CryptMod[ncrypt], from, '|')) != -1
01548 && ncrypt < NCRYPTMAX) {
01549 ncrypt++;
01550 }
01551 RefCip = new XrdCryptoCipher *[ncrypt];
01552 CF = new XrdCryptoFactory *[ncrypt];
01553 if (CF) {
01554 int i = 0;
01555 for (; i < ncrypt; i++ ) {
01556
01557 CF[i] = XrdCryptoFactory::GetCryptoFactory(CryptMod[i].c_str());
01558 if (!CF[i]) {
01559 PRT("// Hook for crypto factory "<<CryptMod[i]<<" undefined");
01560 continue;
01561 }
01562 }
01563 }
01564 }
01565
01566 bool CheckOption(XrdOucString opt, const char *ref, int &ival)
01567 {
01568
01569
01570
01571
01572
01573 bool rc = 0;
01574
01575 int lref = (ref) ? strlen(ref) : 0;
01576 if (!lref)
01577 return rc;
01578 XrdOucString noref = ref;
01579 noref.insert("no",0);
01580
01581 ival = -1;
01582 if (opt == ref) {
01583 ival = 1;
01584 rc = 1;
01585 } else if (opt == noref) {
01586 ival = 0;
01587 rc = 1;
01588 }
01589
01590 return rc;
01591 }
01592
01593 bool AddPassword(XrdSutPFEntry &ent, XrdOucString salt, XrdOucString &ranpwd,
01594 bool random, bool checkpw, bool &newpw)
01595 {
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607 static XrdOucString pwdref;
01608
01609 XrdSutPFBuf oldsalt;
01610 XrdSutPFBuf oldhash;
01611
01612
01613 if (checkpw) {
01614 if (ent.buf1.len > 0 && ent.buf1.buf) {
01615 oldsalt.SetBuf(ent.buf1.buf,ent.buf1.len);
01616 if (ent.buf2.len > 0 && ent.buf2.buf) {
01617 oldhash.SetBuf(ent.buf2.buf,ent.buf2.len);
01618 } else {
01619 checkpw = 0;
01620 }
01621 } else {
01622 checkpw = 0;
01623 }
01624 }
01625
01626
01627 ent.buf1.SetBuf(salt.c_str(),salt.length());
01628
01629
01630 XrdOucString passwd = "";
01631 if (newpw || !pwdref.length()) {
01632 newpw = 1;
01633 pwdref = "";
01634 }
01635 char *pwhash = 0;
01636 int pwhlen = 0;
01637 int natt = 0;
01638 while (!passwd.length()) {
01639
01640
01641 if (natt == kMAXPWDATT) {
01642 PRT("AddPassword: max number of attempts reached: "<<kMAXPWDATT);
01643 if (pwhash) delete[] pwhash;
01644 return 0;
01645 }
01646
01647
01648 if (newpw) {
01649 if (!random) {
01650 XrdOucString prompt = "Password: ";
01651 if (natt == (kMAXPWDATT - 1))
01652 prompt.insert(" (last attempt)",prompt.find(":"));
01653 XrdSutGetPass(prompt.c_str(), passwd);
01654 if (passwd.length()) {
01655 pwdref = passwd;
01656 if (SavePw)
01657 ranpwd = passwd;
01658 newpw = 0;
01659 } else {
01660 natt++;
01661 break;
01662 }
01663 } else if (random) {
01664 XrdSutRndm::GetString(1,8,passwd);
01665 if (IterNum.length() > 0) {
01666
01667
01668 passwd.insert(IterNum,0);
01669 }
01670 pwdref = passwd;
01671 ranpwd = passwd;
01672 newpw = 0;
01673 checkpw = 0;
01674 }
01675 } else {
01676 passwd = pwdref;
01677 }
01678
01679 pwhash = new char[(*KDFunLen)()];
01680 pwhlen = (*KDFun)(passwd.c_str(),passwd.length(),
01681 passwd.c_str(),passwd.length(),pwhash,0);
01682
01683
01684 if (checkpw) {
01685
01686 char *osahash = new char[(*KDFunLen)()];
01687
01688 (*KDFun)(pwhash,pwhlen,
01689 oldsalt.buf,oldsalt.len,osahash,0);
01690 if (!memcmp(oldhash.buf,osahash,oldhash.len)) {
01691
01692 PRT("AddPassword: Password seems to be the same"
01693 ": please enter a different one");
01694 passwd.hardreset();
01695 pwdref.hardreset();
01696 ranpwd.hardreset();
01697 newpw = 1;
01698 }
01699
01700 if (osahash) delete[] osahash;
01701 }
01702 }
01703
01704
01705 if (passwd.length()) {
01706
01707 char *nsahash = new char[(*KDFunLen)()];
01708
01709 int hlen = (*KDFun)(pwhash,pwhlen,
01710 salt.c_str(),salt.length(),nsahash,0);
01711
01712 ent.buf2.SetBuf(nsahash,hlen);
01713
01714 if (nsahash) delete[] nsahash;
01715 }
01716
01717
01718 if (pwhash) delete[] pwhash;
01719
01720 return 1;
01721 }
01722
01723 bool AddPassword(XrdSutPFEntry &ent, bool &newpw, const char *pwd)
01724 {
01725
01726
01727
01728
01729
01730 static XrdOucString pwdref;
01731
01732
01733
01734 XrdOucString passwd = "";
01735 if (newpw || !pwdref.length()) {
01736 newpw = 1;
01737 pwdref = "";
01738 }
01739
01740
01741 if (pwd && strlen(pwd) > 0) {
01742 PRT("AddPassword: using input password ("<<strlen(pwd)<<" bytes)");
01743 passwd = pwd;
01744 }
01745 char *pwhash = 0;
01746 int pwhlen = 0;
01747 int natt = 0;
01748 while (!passwd.length()) {
01749
01750
01751 if (natt == kMAXPWDATT) {
01752 PRT("AddPassword: max number of attempts reached: "<<kMAXPWDATT);
01753 if (pwhash) delete[] pwhash;
01754 return 0;
01755 }
01756
01757
01758 if (newpw) {
01759 XrdOucString prompt = "Password: ";
01760 if (natt == (kMAXPWDATT - 1))
01761 prompt.insert(" (last attempt)",prompt.find(":"));
01762 XrdSutGetPass(prompt.c_str(), passwd);
01763 if (passwd.length()) {
01764 pwdref = passwd;
01765 newpw = 0;
01766 } else {
01767 natt++;
01768 break;
01769 }
01770 } else {
01771 passwd = pwdref;
01772 }
01773 }
01774
01775
01776 if (Hash) {
01777 pwhash = new char[(*KDFunLen)()];
01778 pwhlen = (*KDFun)(passwd.c_str(),passwd.length(),
01779 passwd.c_str(),passwd.length(),pwhash,0);
01780 } else {
01781
01782
01783 pwhlen = passwd.length();
01784 pwhash = new char[pwhlen];
01785 memcpy(pwhash,passwd.c_str(),pwhlen);
01786 }
01787
01788
01789 ent.buf1.SetBuf(pwhash,pwhlen);
01790
01791
01792 if (pwhash) delete[] pwhash;
01793
01794 return 1;
01795 }
01796
01797 void SavePasswd(XrdOucString tag, XrdOucString pwd, bool onetime)
01798 {
01799
01800
01801
01802 if (!tag.length() || !pwd.length()) {
01803 PRT("SavePasswd: tag or pwd undefined - do nothing ("<<
01804 tag.c_str()<<","<<pwd.c_str()<<")");
01805 return;
01806 }
01807
01808 if (!Dir.length()) {
01809 PRT("SavePasswd: main directory undefined - do nothing");
01810 return;
01811 }
01812
01813
01814 PwdFile = Dir;
01815 PwdFile += GenPwdRef;
01816
01817
01818 if (XrdSutMkdir(PwdFile.c_str(),0777) != 0) {
01819 PRT("SavePasswd: Cannot create requested path: "<<PwdFile.c_str());
01820 return;
01821 }
01822
01823
01824 PwdFile += tag;
01825
01826
01827 int fd = open(PwdFile.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0600);
01828 if (fd < 0) {
01829 PRT("SavePasswd: could not open/create file: "<<PwdFile.c_str());
01830 PRT("SavePasswd: errno: "<<errno);
01831 return;
01832 }
01833
01834
01835 XrdOucString buf;
01836 buf += "********* Password information **************\n\n";
01837 buf += "host: "; buf += SrvName; buf += "\n";
01838 buf += "ID: "; buf += SrvID; buf += "\n";
01839 buf += "tag: "; buf += tag; buf += "\n";
01840 buf += "password: "; buf += pwd; buf += "\n";
01841 if (onetime) {
01842 buf += "status: "; buf += 2; buf += "\n";
01843 buf += "\n";
01844 buf += "NB: one-time password: user will be asked for \n";
01845 buf += " new password on first login \n";
01846 } else {
01847 buf += "status: "; buf += 1; buf += "\n";
01848 buf += "\n";
01849 }
01850 buf += "*********************************************";
01851
01852
01853
01854 while (write(fd, buf.c_str(), buf.length()) < 0 && errno == EINTR)
01855 errno = 0;
01856
01857
01858 buf.assign("\n",0);
01859 buf += "********* Server PUK information **************\n\n";
01860 int i = 0;
01861 for (; i < ncrypt; i++) {
01862 XrdOucString ptag = SrvName + ":";
01863 ptag += SrvID; ptag += "_"; ptag += CF[i]->ID();
01864 buf += "puk: "; buf += ptag; buf += "\n";
01865 int lpub = 0;
01866 char *pub = RefCip[i]->Public(lpub);
01867 if (pub) {
01868 buf += pub; buf += "\n";
01869 delete[] pub;
01870 }
01871 buf += "epuk\n";
01872 }
01873 buf += "\n";
01874 buf += "*********************************************";
01875
01876
01877
01878 while (write(fd, buf.c_str(), buf.length()) < 0 && errno == EINTR)
01879 errno = 0;
01880
01881
01882 close (fd);
01883
01884
01885 return;
01886 }
01887
01888 bool GetEntry(XrdSutPFile *ff, XrdOucString tag,
01889 XrdSutPFEntry &ent, bool &check)
01890 {
01891
01892
01893
01894
01895 int nr = ff->ReadEntry(tag.c_str(),ent);
01896 check = 0;
01897 if (nr > 0) {
01898 if (!Force) {
01899 PRT(" Entry for tag '"<<tag.c_str()<<
01900 "' already existing in file: "<<ff->Name());
01901 PRT(" Details: "<<ent.AsString());
01902 PRT(" Use option '-force' to overwrite / update");
01903 return 1;
01904 } else {
01905 check = 1;
01906 }
01907 } else {
01908
01909
01910 ent.SetName(tag.c_str());
01911 ent.cnt = 0;
01912 }
01913 return 0;
01914 }
01915
01916 bool AskConfirm(const char *msg1, bool defact, const char *msg2)
01917 {
01918
01919
01920
01921
01922
01923
01924 bool rc = defact;
01925
01926 if (!Confirm) {
01927 rc = 1;
01928 } else {
01929 if (msg2) PRT(msg2);
01930 XrdOucString ask;
01931 XrdOucString prompt = defact ? " [y]: " : " [n]: ";
01932 if (msg1)
01933 prompt.insert(msg1,0);
01934 XrdSutGetLine(ask,prompt.c_str());
01935 ask.lower(0);
01936 if (ask.length()) {
01937 if (defact && (ask == 'n' || ask == "no")) {
01938 rc = 0;
01939 } else if (!defact && (ask == 'y' || ask == "yes")) {
01940 rc = 1;
01941 }
01942 }
01943 }
01944
01945 return rc;
01946 }
01947
01948 bool ReadPasswd(XrdOucString &tag, XrdOucString &pwd, int &st)
01949 {
01950
01951
01952
01953
01954 if (PwdFile.length() <= 0) {
01955 PRT("ReadPasswd: file name undefined - do nothing");
01956 return 0;
01957 }
01958
01959
01960 FILE *fd = fopen(PwdFile.c_str(),"r");
01961 if (fd == 0) {
01962 PRT("ReadPasswd: could not open file: "<<PwdFile.c_str());
01963 PRT("ReadPasswd: errno: "<<errno);
01964 return 0;
01965 }
01966
01967
01968 XrdOucString usr, host, id;
01969 char line[1024], s1[50], s2[1024];
01970 while (fgets(line, sizeof(line), fd) != 0) {
01971 if (line[strlen(line)-1] == '\n')
01972 line[strlen(line)-1] = 0;
01973 if (strlen(line) <= 0)
01974 continue;
01975 if (sscanf(line,"%s %s",s1,s2) < 2)
01976 continue;
01977 if (!strncmp(s1,"host:",5)) {
01978 host = s2;
01979 } else if (!strncmp(s1,"ID:",3)) {
01980 id = s2;
01981 } else if (!strncmp(s1,"tag:",4)) {
01982 usr = s2;
01983 } else if (!strncmp(s1,"password:",9)) {
01984 pwd = s2;
01985 } else if (!strncmp(s1,"status:",7)) {
01986 st = strtol(s2, 0, 10);
01987 }
01988 }
01989
01990
01991 fclose(fd);
01992
01993
01994 if (usr.length() <= 0 || pwd.length() <= 0) {
01995 if (usr.length() <= 0)
01996 PRT("ReadPasswd: usr tag missing in file "<<PwdFile.c_str());
01997 if (pwd.length() <= 0)
01998 PRT("ReadPasswd: password missing in file "<<PwdFile.c_str());
01999 return 0;
02000 }
02001
02002
02003 if (host.length() <= 0 || id.length() <= 0) {
02004 if (host.length() <= 0)
02005 PRT("ReadPasswd: warning: host name missing in file "
02006 <<PwdFile);
02007 if (id.length() <= 0)
02008 PRT("ReadPasswd: warning: srv ID missing in file "
02009 <<PwdFile);
02010 }
02011
02012
02013 tag = usr;
02014
02015
02016 if (host.length() > 0) {
02017 tag += '@';
02018 tag += host;
02019 tag += ':';
02020 }
02021
02022
02023 if (id.length() > 0) {
02024 tag += id;
02025 }
02026
02027
02028 PRT("ReadPasswd: build tag: "<<tag);
02029
02030
02031
02032 return 1;
02033 }
02034
02035 bool ReadPuk(int &ipuk, XrdOucString *tpuk, XrdOucString *puk)
02036 {
02037
02038
02039
02040
02041 if (PukFile.length() <= 0) {
02042 PRT("ReadPuk: file name undefined - do nothing");
02043 return 0;
02044 }
02045
02046
02047 FILE *fd = fopen(PukFile.c_str(),"r");
02048 if (fd == 0) {
02049 PRT("ReadPuk: could not open file: "<<PukFile.c_str());
02050 PRT("ReadPuk: errno: "<<errno);
02051 return 0;
02052 }
02053
02054
02055 ipuk = 0;
02056 char line[1024], s1[50], s2[1024];
02057 while (fgets(line, sizeof(line), fd) != 0) {
02058 if (line[strlen(line)-1] == '\n')
02059 line[strlen(line)-1] = 0;
02060 if (strlen(line) <= 0)
02061 continue;
02062 if (sscanf(line,"%s %s",s1,s2) < 2)
02063 continue;
02064 if (!strncmp(s1,"puk:",4)) {
02065 if (ipuk < kMAXPUK) {
02066 tpuk[ipuk] = s2;
02067 while (fgets(line, sizeof(line), fd) != 0) {
02068 if (!strncmp(line,"puk:",4) ||
02069 !strncmp(line,"epuk",4) || strlen(line) <= 0)
02070 break;
02071 puk[ipuk] += line;
02072 }
02073 ipuk++;
02074 } else {
02075 PRT("ReadPuk: warning: max number of puks reached ("<<kMAXPUK<<")");
02076 }
02077 }
02078 }
02079
02080
02081 fclose(fd);
02082
02083
02084 PRT("ReadPuk: found "<<ipuk<<" server puks");
02085 int i = 0;
02086 for (; i < ipuk; i++) {
02087
02088
02089 PRT("ReadPuk: build puk tag: "<<tpuk[i]);
02090 }
02091
02092
02093 return 1;
02094 }
02095
02096 bool SavePuk()
02097 {
02098
02099
02100
02101 if (!Dir.length()) {
02102 PRT("SavePuk: main directory undefined - do nothing");
02103 return 0;
02104 }
02105
02106
02107 PukFile = Dir;
02108 PukFile += GenPukRef;
02109
02110
02111 if (XrdSutMkdir(PukFile.c_str(),0777) != 0) {
02112 PRT("SavePuk: Cannot create requested path: "<<PukFile);
02113 return 0;
02114 }
02115
02116
02117 PukFile += "puk.";
02118 int now = time(0);
02119 char *tstr = new char[20];
02120 if (!tstr) {
02121 PRT("SavePuk: Cannot create buffer for time string");
02122 return 0;
02123 }
02124 XrdSutTimeString(now, tstr, 1);
02125 PukFile += tstr;
02126 delete tstr;
02127
02128
02129 int fd = open(PukFile.c_str(),O_WRONLY | O_CREAT | O_TRUNC, 0600);
02130 if (fd < 0) {
02131 PRT("SavePuk: could not open/create file: "<<PukFile);
02132 PRT("SavePuk: errno: "<<errno);
02133 return 0;
02134 }
02135
02136
02137 XrdSutBucket **bck = new XrdSutBucket *[ncrypt];
02138 if (!bck) {
02139 PRT("SavePuk: Cannot create array of temporary buckets");
02140 return 0;
02141 }
02142
02143
02144 int lout = 0, i = 0;
02145 for (; i < ncrypt; i++) {
02146
02147
02148 if (!CF[i] || !RefCip[i]) continue;
02149
02150
02151 bck[i] = RefCip[i]->AsBucket();
02152 if (!bck[i]) continue;
02153
02154
02155 lout += (bck[i]->size + 2*sizeof(kXR_int32));
02156 }
02157
02158
02159 char *bout = new char[lout];
02160 if (!bout) {
02161 PRT("SavePuk: Cannot create output buffer");
02162 close(fd);
02163 return 0;
02164 }
02165
02166
02167 int lp = 0;
02168 for (i = 0; i < ncrypt; i++) {
02169
02170
02171 if (!CF[i] || !bck[i]) continue;
02172
02173
02174 kXR_int32 id = CF[i]->ID();
02175 memcpy(bout+lp,&id,sizeof(kXR_int32));
02176 lp += sizeof(kXR_int32);
02177
02178
02179 kXR_int32 lpuk = bck[i]->size;
02180 memcpy(bout+lp,&lpuk,sizeof(kXR_int32));
02181 lp += sizeof(kXR_int32);
02182
02183
02184 memcpy(bout+lp,bck[i]->buffer,lpuk);
02185 lp += lpuk;
02186
02187
02188 delete bck[i];
02189 bck[i] = 0;
02190 }
02191 delete[] bck;
02192
02193
02194
02195 while (write(fd, bout, lout) < 0 && errno == EINTR)
02196 errno = 0;
02197 PRT("SavePuk: "<<lout<<" bytes written to file "<<PukFile);
02198
02199
02200 close (fd);
02201
02202
02203 return 1;
02204 }
02205
02206 bool ReadPuk()
02207 {
02208
02209
02210
02211 if (PukFile.length() <= 0) {
02212 PRT("ReadPuk: file name undefined - do nothing");
02213 return 0;
02214 }
02215
02216
02217 int fd = open(PukFile.c_str(),O_RDONLY);
02218 if (fd < 0) {
02219 PRT("ReadPuk: could not open file: "<<PukFile.c_str());
02220 PRT("ReadPuk: errno: "<<errno);
02221 return 0;
02222 }
02223
02224
02225
02226 int nr = 0, nrdt = 0, ncip = 0;
02227 kXR_int32 id = 0, lpuk = 0;
02228
02229 while ((nr = read(fd,&id,sizeof(kXR_int32))) == sizeof(kXR_int32)) {
02230 nrdt += nr;
02231
02232 if ((nr = read(fd,&lpuk,sizeof(kXR_int32))) != sizeof(kXR_int32)) {
02233 PRT("ReadPuk: could not read puk length - corrupton ? ");
02234 close(fd);
02235 return 0;
02236 }
02237 nrdt += nr;
02238
02239 char *puk = new char[lpuk];
02240 if (!puk) {
02241 PRT("ReadPuk: could not allocate buffer for puk");
02242 close(fd);
02243 return 0;
02244 }
02245 if ((nr = read(fd, puk, lpuk)) != lpuk) {
02246 PRT("ReadPuk: could not read puk buffer - corrupton ? ");
02247 close(fd);
02248 return 0;
02249 }
02250 nrdt += nr;
02251
02252 XrdSutBucket *bck = new XrdSutBucket(puk, lpuk);
02253 if (!bck) {
02254 PRT("ReadPuk: could not create bucket for puk");
02255 delete[] puk;
02256 close(fd);
02257 return 0;
02258 }
02259
02260 int i = ncrypt - 1;
02261 while (i >= 0) {
02262 if (CF[i] && CF[i]->ID() == id) break;
02263 i--;
02264 }
02265 if (i < 0) {
02266 PRT("ReadPuk: warning: factory with ID "<< id << " not found");
02267 delete bck;
02268 continue;
02269 }
02270
02271 RefCip[i] = CF[i]->Cipher(bck);
02272 if (!RefCip[i]) {
02273 PRT("ReadPuk: warning: could not instantiate cipher"
02274 " from bucket for factory "<<CF[i]->Name());
02275 } else {
02276 PRT("ReadPuk: instantiate cipher for factory "<<CF[i]->Name());
02277 }
02278
02279 ncip++;
02280 delete bck;
02281 }
02282
02283
02284 close (fd);
02285
02286 PRT("ReadPuk: "<<nrdt<<" bytes read from file "<<PukFile);
02287 PRT("ReadPuk: "<<ncip<<" ciphers instantiated");
02288
02289
02290 return 1;
02291 }
02292
02293 int GeneratePuk()
02294 {
02295
02296
02297 int ncf = 0, i = 0;
02298 for (; i < ncrypt; i++ ) {
02299
02300 CF[i] = XrdCryptoFactory::GetCryptoFactory(CryptMod[i].c_str());
02301 if (!CF[i]) {
02302 PRT("// Hook for crypto factory "<<CryptMod[i]<<" undefined");
02303 continue;
02304 }
02305
02306
02307 RefCip[i] = CF[i]->Cipher(0,0,0);
02308 if (!RefCip[i]) continue;
02309
02310
02311 ncf++;
02312 }
02313
02314
02315 return ncf;
02316 }
02317
02318 int LocateFactoryIndex(char *tag, int &id)
02319 {
02320
02321
02322
02323
02324
02325 XrdOucString sid(tag);
02326 sid.erase(0,sid.rfind('_')+1);
02327 id = atoi(sid.c_str());
02328 int j = ncrypt - 1;
02329 while (j >= 0) {
02330 if (CF[j] && CF[j]->ID() == id) break;
02331 j--;
02332 }
02333 if (j < 0)
02334 PRT("// warning: factory with ID "<< id << " not found");
02335
02336 return j;
02337 }
02338
02339 bool ExpPuk(const char *puk, bool read)
02340 {
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350 if (read) {
02351
02352 XrdOucString genpukdir = Dir;
02353 genpukdir += GenPukRef;
02354
02355
02356 if (puk && strlen(puk) > 0) {
02357
02358 if (puk[0] != '/')
02359 PukFile = genpukdir;
02360 PukFile += puk;
02361 } else {
02362
02363 DIR *dir = opendir(genpukdir.c_str());
02364 if (!dir) {
02365 PRT("ExpPuk: cannot open standard genpuk dir "<<genpukdir);
02366 return 0;
02367 }
02368 dirent *ent = 0;
02369 time_t latest = -1;
02370 while ((ent = readdir(dir))) {
02371
02372 if (strncmp(ent->d_name, "puk.", 4))
02373 continue;
02374
02375 XrdOucString fn = genpukdir;
02376 fn += ent->d_name;
02377 struct stat st;
02378 if (stat(fn.c_str(), &st) != 0) {
02379 PRT("ExpPuk: cannot stat "<<fn<<" - skipping");
02380 continue;
02381 }
02382 if (st.st_mtime > latest) {
02383 PukFile = fn;
02384 latest = st.st_mtime;
02385 }
02386 }
02387 }
02388
02389
02390 if (!ReadPuk()) {
02391 PRT("ExpPuk: problem reading the key in");
02392 return 0;
02393 }
02394 }
02395
02396
02397 XrdOucString expfile = PukFile;
02398 expfile += ".export";
02399 PRT("ExpPuk: exporting key from file "<<PukFile);
02400
02401
02402
02403 int fd = open(expfile.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
02404 if (fd < 0) {
02405 PRT("ExpPuk: could not open/create file: "<<expfile.c_str());
02406 PRT("ExpPuk: errno: "<<errno);
02407 return 0;
02408 }
02409
02410
02411 XrdOucString buf;
02412 buf.assign("\n",0);
02413 buf += "********* Server PUK information **************\n\n";
02414 int i = 0;
02415 for (; i < ncrypt; i++) {
02416 XrdOucString ptag = SrvName + ":";
02417 ptag += SrvID; ptag += "_"; ptag += CF[i]->ID();
02418 buf += "puk: "; buf += ptag; buf += "\n";
02419 int lpub = 0;
02420 char *pub = RefCip[i]->Public(lpub);
02421 if (pub) {
02422 buf += pub; buf += "\n";
02423 delete[] pub;
02424 }
02425 buf += "epuk\n";
02426 }
02427 buf += "\n";
02428 buf += "*********************************************";
02429
02430
02431
02432 while (write(fd, buf.c_str(), buf.length()) < 0 && errno == EINTR)
02433 errno = 0;
02434
02435
02436 close (fd);
02437
02438
02439 return 1;
02440 }