Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TAuthenticate.cxx
Go to the documentation of this file.
1// @(#)root/auth:$Id: f2cfa663e232707e1201467b5805ff1d13575326 $
2// Author: Fons Rademakers 26/11/2000
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12//////////////////////////////////////////////////////////////////////////
13// //
14// TAuthenticate //
15// //
16// An authentication module for ROOT based network services, like rootd // //
17// //
18//////////////////////////////////////////////////////////////////////////
19
20#include "RConfigure.h"
21
22#include "TAuthenticate.h"
23#include "TApplication.h"
24#include "THostAuth.h"
25#include "TRootSecContext.h"
26#include "TPluginManager.h"
27#include "TNetFile.h"
28#include "TPSocket.h"
29#include "TMessage.h"
30#include "TSystem.h"
31#include "TError.h"
32#include "Getline.h"
33#include "TROOT.h"
34#include "TEnv.h"
35#include "TList.h"
36#include "NetErrors.h"
37#include "TRegexp.h"
38#include "TVirtualMutex.h"
39#include "TTimer.h"
40#include "TBase64.h"
41#include "strlcpy.h"
42#include "snprintf.h"
43
44#include "rsafun.h"
45
46#ifndef R__LYNXOS
47#include <sys/stat.h>
48#endif
49#include <cerrno>
50#include <sys/types.h>
51#include <ctime>
52#if !defined(R__WIN32) && !defined(R__MACOSX) && !defined(R__FBSD) && \
53 !defined(R__OBSD)
54#include <crypt.h>
55#endif
56#ifdef WIN32
57# include <io.h>
58#endif /* WIN32 */
59#if defined(R__LINUX) || defined(R__FBSD) || defined(R__OBSD)
60# include <unistd.h>
61#endif
62#include <cstdlib>
63#ifndef WIN32
64# include <sys/time.h>
65#endif /* WIN32 */
66
67#if defined(R__MACOSX)
68extern "C" char *crypt(const char *, const char *);
69#endif
70
71#ifdef R__SSL
72// SSL specific headers
73# include <openssl/bio.h>
74# include <openssl/err.h>
75# include <openssl/pem.h>
76# include <openssl/rand.h>
77# include <openssl/rsa.h>
78# include <openssl/ssl.h>
79# include <openssl/blowfish.h>
80#endif
81
82#ifdef R__SSL
83 static BF_KEY fgBFKey; // Blowfish symmetric key
84#endif
85
86namespace ROOT::Deprecated {
87
91
92// Statics initialization
94TString TAuthenticate::fgAuthMeth[] = { "UsrPwd", "Unsupported", "Unsupported",
95 "Unsupported", "Unsupported", "Unsupported" };
99TDatime TAuthenticate::fgLastAuthrc; // Time of last reading of fgRootAuthrc
104Bool_t TAuthenticate::fgReadHomeAuthrc = kTRUE; // on/off search for $HOME/.rootauthrc
105TString TAuthenticate::fgRootAuthrc; // Path to last rootauthrc-like file read
106Int_t TAuthenticate::fgRSAKey = -1; // Default RSA key type to be used
116Int_t TAuthenticate::fgAuthTO = -2; // Timeout value
117
118// ID of the main thread as unique identifier
120
122
123} // namespace ROOT::Deprecated
124
126
127// Standard version of Sec Context match checking
129
130
131
132////////////////////////////////////////////////////////////////////////////////
133/// rand() implementation using /udev/random or /dev/random, if available
134
135static int auth_rand()
136{
137#ifndef WIN32
138 int frnd = open("/dev/urandom", O_RDONLY);
139 if (frnd < 0) frnd = open("/dev/random", O_RDONLY);
140 int r;
141 if (frnd >= 0) {
142 ssize_t rs = read(frnd, (void *) &r, sizeof(int));
143 close(frnd);
144 if (r < 0) r = -r;
145 if (rs == sizeof(int)) return r;
146 }
147 Printf("+++ERROR+++ : auth_rand: neither /dev/urandom nor /dev/random are available or readable!");
148 struct timeval tv;
149 if (gettimeofday(&tv,0) == 0) {
150 int t1, t2;
151 memcpy((void *)&t1, (void *)&tv.tv_sec, sizeof(int));
152 memcpy((void *)&t2, (void *)&tv.tv_usec, sizeof(int));
153 r = t1 + t2;
154 if (r < 0) r = -r;
155 return r;
156 }
157 return -1;
158#else
159 // No special random device available: use rand()
160 return rand();
161#endif
162}
163
164////////////////////////////////////////////////////////////////////////////////
165/// Create authentication object.
166
167ROOT::Deprecated::TAuthenticate::TAuthenticate(TSocket *sock, const char *remote, const char *proto, const char *user)
168{
169 if (gDebug > 2 && gAuthenticateMutex)
170 Info("Authenticate", "locking mutex (pid: %d)",gSystem->GetPid());
172
173 // Use the ID of the starting thread as unique identifier
174 if (fgProcessID < 0)
176
177 if (fgAuthTO == -2)
178 fgAuthTO = gEnv->GetValue("Auth.Timeout",-1);
179
180 fSocket = sock;
181 fRemote = remote;
182 fHostAuth = 0;
183 fVersion = 5; // The latest, by default
184 fSecContext = 0;
185
186 if (gDebug > 2)
187 Info("TAuthenticate", "Enter: local host: %s, user is: %s (proto: %s)",
188 gSystem->HostName(), user, proto);
189
190 // Set protocol string.
191 // Check if version should be different ...
192 char *pdd;
194 if (proto && strlen(proto) > 0) {
195 char *sproto = StrDup(proto);
196 if ((pdd = strstr(sproto, ":")) != 0) {
197 int rproto = atoi(pdd + 1);
198 *pdd = '\0';
199 if (strstr(sproto, "root") != 0) {
200 if (rproto < 12 ) {
201 fVersion = 4;
202 if (rproto < 11 ) {
203 fVersion = 3;
204 if (rproto < 9 ) {
205 fVersion = 2;
206 if (rproto < 8) {
207 fVersion = 1;
208 if (rproto < 6)
209 fVersion = 0;
210 }
211 }
212 }
213 }
215 }
216 if (gDebug > 3)
217 Info("TAuthenticate",
218 "service: %s (remote protocol: %d): fVersion: %d", sproto,
220 }
222 delete [] sproto;
223 }
224
225 // Check or get user name
226 fUser = "";
228 if (user && strlen(user) > 0) {
229 fUser = user;
230 checkUser = user;
231 } else {
233 if (u)
234 checkUser = u->fUser;
235 delete u;
236 }
237 fPasswd = "";
238 fPwHash = kFALSE;
239
240 // Type of RSA key
241 if (fgRSAKey < 0) {
242 fgRSAKey = 0; // Default key
243#ifdef R__SSL
244 // Another choice possible: check user preferences
245 if (gEnv->GetValue("RSA.KeyType",0) == 1)
246 fgRSAKey = 1;
247#endif
248 }
249 // This is the key actually used: we propose the default
250 // to the server, and behave according to its reply
252 if (gDebug > 3)
253 Info("TAuthenticate","RSA key: default type %d", fgRSAKey);
254
255 // RSA key generation (one per session)
256 if (!fgRSAInit) {
257 GenRSAKeys();
258 fgRSAInit = 1;
259 }
260
261 // Check and save the host FQDN ...
264 if (addr.IsValid())
265 fqdn = addr.GetHostName();
267 fqdnsrv.Form("%s:%d",fqdn.Data(),servtype);
268
269 // Read directives from files; re-read if files have changed
271
272 if (gDebug > 3) {
273 Info("TAuthenticate",
274 "number of HostAuth Instantiations in memory: %d",
275 GetAuthInfo()->GetSize());
278 }
279
280 // Check the list of auth info for already loaded info about this host
282
283 //
284 // If generic THostAuth (i.e. with wild card or user == any)
285 // make a personalized memory copy of this THostAuth
286 if (strchr(fHostAuth->GetHost(),'*') || strchr(fHostAuth->GetHost(),'*') ||
287 fHostAuth->GetServer() == -1 ) {
292 }
293
294 // If a specific method has been requested via the protocol
295 // set it as first
296 Int_t sec = -1;
298 tmp.ReplaceAll("root",4,"",0);
299 tmp.ReplaceAll("sock",4,"",0);
300 if (!strncmp(tmp.Data(),"up",2))
301 sec = 0;
302 else if (!strncmp(tmp.Data(),"s",1))
303 sec = 1;
304 else if (!strncmp(tmp.Data(),"k",1))
305 sec = 2;
306 else if (!strncmp(tmp.Data(),"g",1))
307 sec = 3;
308 else if (!strncmp(tmp.Data(),"h",1))
309 sec = 4;
310 else if (!strncmp(tmp.Data(),"ug",2))
311 sec = 5;
312 if (sec > -1 && sec < kMAXSEC) {
313 if (fHostAuth->HasMethod(sec)) {
315 } else {
316 char *dtmp = GetDefaultDetails(sec, 1, checkUser);
319 if (dtmp)
320 delete [] dtmp;
321 }
322 }
323
324 // This is what we have in memory
325 if (gDebug > 3) {
326 TIter next(fHostAuth->Established());
327 TRootSecContext *ctx;
328 while ((ctx = (TRootSecContext *) next()))
329 ctx->Print("0");
330 }
331}
332
333////////////////////////////////////////////////////////////////////////////////
334/// Called in connection with a timer timeout
335
337{
338 Info("CatchTimeOut", "%d sec timeout expired (protocol: %s)",
339 fgAuthTO, fgAuthMeth[fSecurity].Data());
340
341 fTimeOut = 1;
342 if (fSocket)
343 fSocket->Close("force");
344
345 return;
346}
347
348////////////////////////////////////////////////////////////////////////////////
349/// Authenticate to remote rootd server. Return kTRUE if
350/// authentication succeeded.
351
353{
354 if (gDebug > 2 && gAuthenticateMutex)
355 Info("Authenticate", "locking mutex (pid: %d)",gSystem->GetPid());
357
358 Bool_t rc = kFALSE;
359 Int_t st = -1;
360 Int_t remMeth = 0, rMth[kMAXSEC], tMth[kMAXSEC] = {0};
361 Int_t meth = 0;
362 char noSupport[80] = { 0 };
363 char triedMeth[80] = { 0 };
364 Int_t ntry = 0;
365
366 TString user, passwd;
368
369 if (gDebug > 2)
370 Info("Authenticate", "enter: fUser: %s", fUser.Data());
371
372 //
373 // Setup timeout timer, if required
374 TTimer *alarm = 0;
375 if (fgAuthTO > 0) {
376 alarm = new TTimer(0, kFALSE);
377 alarm->SetInterruptSyscalls();
378 // The method CatchTimeOut will be called at timeout
379 alarm->Connect("Timeout()", "TAuthenticate", this, "CatchTimeOut()");
380 }
381
382negotia:
383 st = -1;
384 tMth[meth] = 1;
385 ntry++;
386 if (gDebug > 2)
387 Info("Authenticate", "try #: %d", ntry);
388
389 user = "";
390 passwd = "";
391 pwhash = kFALSE;
392
393 // Security level from the list (if not in cleanup mode ...)
394 fSecurity = (ESecurity) fHostAuth->GetMethod(meth);
395 fDetails = fHostAuth->GetDetails((Int_t) fSecurity);
396 if (gDebug > 2)
397 Info("Authenticate",
398 "trying authentication: method:%d, default details:%s",
399 fSecurity, fDetails.Data());
400
401 // Keep track of tried methods in a list
402 if (triedMeth[0] != '\0')
403 (void) strlcat(triedMeth, " ", sizeof(triedMeth) - 1);
404
405 (void) strlcat(triedMeth, fgAuthMeth[fSecurity].Data(), sizeof(triedMeth) - 1);
406
407 // Set environments
408 SetEnvironment();
409
410 //
411 // Reset timeout variables and start timer
412 fTimeOut = 0;
413 if (fgAuthTO > 0 && alarm) {
414 alarm->Start(fgAuthTO*1000, kTRUE);
415 }
416
417 // Auth calls depend of fSec
418 if (fSecurity == kClear) {
419
420 rc = kFALSE;
421
422 // UsrPwd Authentication
423 user = fgDefaultUser;
424 if (user != "")
425 CheckNetrc(user, passwd, pwhash, kFALSE);
426 if (passwd == "") {
427 if (fgPromptUser) {
428 char *u = PromptUser(fRemote);
429 user = u;
430 delete[] u;
431 }
432 rc = GetUserPasswd(user, passwd, pwhash, kFALSE);
433 }
434 fUser = user;
435 fPasswd = passwd;
436
437 if (!rc) {
438
439 if (fUser != "root")
440 st = ClearAuth(user, passwd, pwhash);
441 } else {
442 Error("Authenticate",
443 "unable to get user name for UsrPwd authentication");
444 }
445
446 }
447
448 // Stop timer
449 if (alarm) alarm->Stop();
450
451 // Flag timeout condition
452 st = (fTimeOut > 0) ? -3 : st;
453
454 //
455 // Analyse the result now ...
456 // Type of action after the analysis:
457 // 0 = return, 1 = negotiation, 2 = send kROOTD_BYE + 3,
458 // 3 = print failure and return
459 Int_t action = 0;
460 Int_t nmet = fHostAuth->NumMethods();
461 Int_t remloc = nmet - ntry;
462 if (gDebug > 0)
463 Info("Authenticate","remloc: %d, ntry: %d, meth: %d, fSecurity: %d",
464 remloc, ntry, meth, fSecurity);
465 Int_t kind, stat;
466 switch (st) {
467
468 case 1:
469 //
470 // Success
471 fHostAuth->CountSuccess((Int_t)fSecurity);
472 if (gDebug > 2)
473 fSecContext->Print();
474 if (fSecContext->IsActive())
475 fSecContext->AddForCleanup(fSocket->GetPort(),
476 fSocket->GetRemoteProtocol(),fSocket->GetServType());
477 rc = kTRUE;
478 break;
479
480 case 0:
481 //
482 // Failure
483 fHostAuth->CountFailure((Int_t)fSecurity);
484 if (fVersion < 2) {
485 //
486 // Negotiation not supported by old daemons ...
487 if (gDebug > 2)
488 Info("Authenticate",
489 "negotiation not supported remotely: try next method, if any");
490 if (meth < nmet - 1) {
491 meth++;
492 action = 1;
493 } else {
494 action = 2;
495 }
496 rc = kFALSE;
497 break;
498 }
499 //
500 // Attempt negotiation ...
501 if (fSocket->Recv(stat, kind) < 0) {
502 action = 0;
503 rc = kFALSE;
504 }
505 if (gDebug > 2)
506 Info("Authenticate",
507 "after failed attempt: kind= %d, stat= %d", kind, stat);
508 if (kind == kROOTD_ERR) {
509 action = 2;
510 rc = kFALSE;
511 } else if (kind == kROOTD_NEGOTIA) {
512 if (stat > 0) {
513 int len = 3 * stat;
514 char *answer = new char[len];
515 int nrec = fSocket->Recv(answer, len, kind); // returns user
516 if (nrec < 0) {
517 delete[] answer; // delete buffer while it exit switch() scope
518 action = 0;
519 rc = kFALSE;
520 break;
521 }
522 if (kind != kMESS_STRING)
523 Warning("Authenticate",
524 "strings with accepted methods not received (%d:%d)",
525 kind, nrec);
526 remMeth =
527 sscanf(answer, "%d %d %d %d %d %d", &rMth[0], &rMth[1],
528 &rMth[2], &rMth[3], &rMth[4], &rMth[5]);
529 if (gDebug > 0 && remloc > 0)
530 Info("Authenticate",
531 "remotely allowed methods not yet tried: %s",
532 answer);
533 delete[] answer;
534 } else if (stat == 0) {
535 Info("Authenticate",
536 "no more methods accepted remotely to be tried");
537 action = 3;
538 rc = kFALSE;
539 break;
540 }
541 // If no more local methods, return
542 if (remloc < 1) {
543 action = 2;
544 rc = kFALSE;
545 break;
546 }
547 // Look if a non-tried method matches
548 int i, j;
549 std::string available{};
551 for (i = 0; i < remMeth; i++) {
552 for (j = 0; j < nmet; j++) {
553 if (fHostAuth->GetMethod(j) == rMth[i] && tMth[j] == 0) {
554 meth = j;
555 action = 1;
557 break;
558 }
559 if (i == 0)
560 available += " " + std::to_string(fHostAuth->GetMethod(j));
561 }
562 if (methfound) break;
563 }
564 if (methfound) break;
565 //
566 // No method left to be tried: notify and exit
567 if (gDebug > 0)
568 Warning("Authenticate", "no match with those locally available: %s", available.c_str());
569 action = 2;
570 rc = kFALSE;
571 break;
572 } else { // unknown message code at this stage
573 action = 3;
574 rc = kFALSE;
575 break;
576 }
577 break;
578
579 case -1:
580 //
581 // Method not supported
582 fHostAuth->CountFailure((Int_t)fSecurity);
583 if (gDebug > 2)
584 Info("Authenticate",
585 "method not even started: insufficient or wrong info: %s",
586 "try with next method, if any");
587 fHostAuth->RemoveMethod(fSecurity);
588 nmet--;
589 if (nmet > 0) {
590 action = 1;
591 } else
592 action = 2;
593
594 break;
595
596 case -2:
597 //
598 // Remote host does not accepts connections from local host
599 fHostAuth->CountFailure((Int_t)fSecurity);
600 if (fVersion <= 2)
601 if (gDebug > 2)
602 Warning("Authenticate",
603 "status code -2 not expected from old daemons");
604 rc = kFALSE;
605 break;
606
607 case -3:
608 //
609 // Timeout: we set the method as last one, should the caller
610 // decide to retry, if it will attempt first something else.
611 // (We can not retry directly, because the server will not be
612 // synchronized ...)
613 fHostAuth->CountFailure((Int_t)fSecurity);
614 if (gDebug > 2)
615 Info("Authenticate", "got a timeout");
616 fHostAuth->SetLast(fSecurity);
617 if (meth < nmet - 1) {
618 fTimeOut = 2;
619 } else
620 fTimeOut = 1;
621 rc = kFALSE;
622 break;
623
624 default:
625 fHostAuth->CountFailure((Int_t)fSecurity);
626 if (gDebug > 2)
627 Info("Authenticate", "unknown status code: %d - assume failure",st);
628 rc = kFALSE;
629 action = 0;
630 break;
631 }
632
633 switch (action) {
634 case 1:
635 goto negotia;
636 // No break but we go away anyhow
637 case 2:
638 fSocket->Send("0", kROOTD_BYE);
639 // fallthrough
640 case 3:
641 if (strlen(noSupport) > 0)
642 Info("Authenticate", "attempted methods %s are not supported"
643 " by remote server version", noSupport);
644 Info("Authenticate",
645 "failure: list of attempted methods: %s", triedMeth);
646 AuthError("Authenticate",-1);
647 rc = kFALSE;
648 break;
649 default:
650 break;
651 }
652
653 // Cleanup timer
655
656 return rc;
657
658}
659
660////////////////////////////////////////////////////////////////////////////////
661/// Set default authentication environment. The values are inferred
662/// from fSecurity and fDetails.
663
665{
667
668 if (gDebug > 2)
669 Info("SetEnvironment",
670 "setting environment: fSecurity:%d, fDetails:%s", fSecurity,
671 fDetails.Data());
672
673 // Defaults
674 fgDefaultUser = fgUser;
675 fgAuthReUse = kTRUE;
676 fgPromptUser = kFALSE;
677
678 // Decode fDetails, is non empty ...
679 if (fDetails != "") {
680 char usdef[kMAXPATHLEN] = { 0 };
681 char pt[5] = { 0 }, ru[5] = { 0 };
682 Int_t hh = 0, mm = 0;
683 char us[kMAXPATHLEN] = {0}, cp[kMAXPATHLEN] = {0};
684 const char *ptr;
685
686 TString usrPromptDef = TString(GetAuthMethod(fSecurity)) + ".LoginPrompt";
687 if ((ptr = strstr(fDetails, "pt:")) != 0) {
688 sscanf(ptr + 3, "%4s %8191s", pt, usdef);
689 } else {
690 if (!strncasecmp(gEnv->GetValue(usrPromptDef,""),"no",2) ||
691 !strncmp(gEnv->GetValue(usrPromptDef,""),"0",1))
692 strncpy(pt,"0",2);
693 else
694 strncpy(pt,"1",2);
695 }
696 TString usrReUseDef = TString(GetAuthMethod(fSecurity)) + ".ReUse";
697 if ((ptr = strstr(fDetails, "ru:")) != 0) {
698 sscanf(ptr + 3, "%4s %8191s", ru, usdef);
699 } else {
700 if (!strncasecmp(gEnv->GetValue(usrReUseDef,""),"no",2) ||
701 !strncmp(gEnv->GetValue(usrReUseDef,""),"0",1))
702 strncpy(ru,"0",2);
703 else
704 strncpy(ru,"1",2);
705 }
706 TString usrValidDef = TString(GetAuthMethod(fSecurity)) + ".Valid";
708 Int_t pd = 0;
709 if ((pd = hours.Index(":")) > -1) {
711 hours.Resize(pd);
712 minutes.Replace(0,pd+1,"");
713 hh = atoi(hours.Data());
714 mm = atoi(minutes.Data());
715 } else {
716 hh = atoi(hours.Data());
717 mm = 0;
718 }
719
720 // Now action depends on method ...
721 if (fSecurity == kClear) {
722 if ((ptr = strstr(fDetails, "us:")) != 0)
723 sscanf(ptr + 3, "%8191s %8191s", us, usdef);
724 if ((ptr = strstr(fDetails, "cp:")) != 0)
725 sscanf(ptr + 3, "%8191s %8191s", cp, usdef);
726 if (gDebug > 2)
727 Info("SetEnvironment", "details:%s, pt:%s, ru:%s, us:%s cp:%s",
728 fDetails.Data(), pt, ru, us, cp);
729 } else {
730 if ((ptr = strstr(fDetails, "us:")) != 0)
731 sscanf(ptr + 3, "%8191s %8191s", us, usdef);
732 if (gDebug > 2)
733 Info("SetEnvironment", "details:%s, pt:%s, ru:%s, us:%s",
734 fDetails.Data(), pt, ru, us);
735 }
736
737 // Set Prompt flag
738 if (!strncasecmp(pt, "yes",3) || !strncmp(pt, "1", 1))
739 fgPromptUser = kTRUE;
740
741 // Set Expiring date
742 fgExpDate = TDatime();
743 fgExpDate.Set(fgExpDate.Convert() + hh*3600 + mm*60);
744
745 // UnSet Crypt flag for UsrPwd, if requested
746 if (fSecurity == kClear) {
747 fgUsrPwdCrypt = kTRUE;
748 if (!strncmp(cp, "no", 2) || !strncmp(cp, "0", 1))
749 fgUsrPwdCrypt = kFALSE;
750 }
751 // Build UserDefaults
752 usdef[0] = '\0';
753 // give highest priority to command-line specification
754 if (fUser == "") {
755 if (strlen(us) > 0) snprintf(usdef, kMAXPATHLEN, "%s", us);
756 } else {
757 snprintf(usdef, kMAXPATHLEN, "%s", fUser.Data());
758 }
759
760 if (strlen(usdef) > 0) {
761 fgDefaultUser = usdef;
762 } else {
763 if (fgUser != "") {
764 fgDefaultUser = fgUser;
765 } else {
767 if (u)
768 fgDefaultUser = u->fUser;
769 delete u;
770 }
771 }
772 if (fgDefaultUser == "anonymous" || fgDefaultUser == "rootd" ||
773 fgUser != "" || fUser != "") {
774 // when set by user don't prompt for it anymore
775 fgPromptUser = kFALSE;
776 }
777
778 if (gDebug > 2)
779 Info("SetEnvironment", "usdef:%s", fgDefaultUser.Data());
780 }
781}
782
783////////////////////////////////////////////////////////////////////////////////
784/// Try to get user name and passwd from several sources.
785
787{
788 if (srppwd) {
789 Error("GetUserPasswd", "SRP no longer supported by ROOT");
790 return 1;
791 }
792
793 if (gDebug > 3)
794 Info("GetUserPasswd", "Enter: User: '%s' Hash:%d SRP:%d",
795 user.Data(),(Int_t)pwhash,(Int_t)false);
796
797 // Get user and passwd set via static functions SetUser and SetPasswd.
798 if (user == "" && fgUser != "")
799 user = fgUser;
800
801 if (fgUser != "" && user == fgUser) {
802 if (passwd == "" && fgPasswd != "") {
803 passwd = fgPasswd;
804 pwhash = fgPwHash;
805 }
806 }
807
808 if (gDebug > 3)
809 Info("GetUserPasswd", "In memory: User: '%s' Hash:%d",
810 user.Data(),(Int_t)pwhash);
811
812 // Check system info for user if still not defined
813 if (user == "") {
815 if (u)
816 user = u->fUser;
817 delete u;
818 if (gDebug > 3)
819 Info("GetUserPasswd", "In memory: User: '%s' Hash:%d",
820 user.Data(),(Int_t)pwhash);
821 }
822
823 // Check ~/.rootnetrc and ~/.netrc files if user was not set via
824 // the static SetUser() method.
825 if (user == "" || passwd == "") {
826 if (gDebug > 3)
827 Info("GetUserPasswd", "Checking .netrc family ...");
828 CheckNetrc(user, passwd, pwhash, /* srppwd */ false);
829 }
830 if (gDebug > 3)
831 Info("GetUserPasswd", "From .netrc family: User: '%s' Hash:%d",
832 user.Data(),(Int_t)pwhash);
833
834 // If user also not set via ~/.rootnetrc or ~/.netrc ask user.
835 if (user == "") {
836 char *p = PromptUser(fRemote);
837 user = p;
838 delete [] p;
839 if (user == "") {
840 Error("GetUserPasswd", "user name not set");
841 return 1;
842 }
843 }
844
845 return 0;
846}
847
848////////////////////////////////////////////////////////////////////////////////
849/// Try to get user name and passwd from the ~/.rootnetrc or
850/// ~/.netrc files. For more info see the version with 4 arguments.
851/// This version is maintained for backward compatability reasons.
852
854{
855 Bool_t hash = false;
856 return CheckNetrc(user, passwd, hash, /* srppwd */ false);
857}
858
859////////////////////////////////////////////////////////////////////////////////
860/// Try to get user name and passwd from the ~/.rootnetrc or
861/// ~/.netrc files. First ~/.rootnetrc is tried, after that ~/.netrc.
862/// These files will only be used when their access masks are 0600.
863/// Returns kTRUE if user and passwd were found for the machine
864/// specified in the URL. If kFALSE, user and passwd are "".
865/// The boolean pwhash is set to kTRUE if the returned passwd is to
866/// be understood as password hash, i.e. if the 'password-hash' keyword
867/// is found in the 'machine' lines; not implemented for 'secure'
868/// and the .netrc file.
869/// The format of these files are:
870///
871/// # this is a comment line
872/// machine `<machine fqdn>` login `<user>` password `<passwd>`
873/// machine `<machine fqdn>` login `<user>` password-hash `<passwd>`
874///
875/// and in addition ~/.rootnetrc also supports:
876///
877/// secure `<machine fqdn>` login `<user>` password `<passwd>`
878///
879/// `<machine fqdn>` may be a domain name or contain the wild card '*'.
880///
881/// for the secure protocols. All lines must start in the first column.
882
884{
885 if (srppwd) {
886 Error("CheckNetrc", "SRP no longer supported by ROOT");
887 return 1;
888 }
889
891 Bool_t first = kTRUE;
892 TString remote = fRemote;
893
894 passwd = "";
895 pwhash = kFALSE;
896
897 TString temp_rootnet = ".rootnetrc";
898 const char *net =
900
901 // Determine FQDN of the host ...
903 if (addr.IsValid())
904 remote = addr.GetHostName();
905
906again:
907 // Only use file when its access rights are 0600
908 FileStat_t buf;
909 if (gSystem->GetPathInfo(net, buf) == 0) {
910#ifdef WIN32
911 // Since Win32 does not have proper protections use file always
912 bool mode0600 = true;
913#else
914 bool mode0600 = (buf.fMode & 0777) == (kS_IRUSR | kS_IWUSR);
915#endif
916 if (R_ISREG(buf.fMode) && !R_ISDIR(buf.fMode) && mode0600) {
917 FILE *fd = fopen(net, "r");
918 char line[256];
919 while (fgets(line, sizeof(line), fd) != 0) {
920 if (line[0] == '#')
921 continue;
922 char word[6][64];
923 int nword = sscanf(line, "%63s %63s %63s %63s %63s %63s",
924 word[0], word[1], word[2], word[3], word[4], word[5]);
925 if (nword != 6)
926 continue;
927 if (strcmp(word[0], "machine"))
928 continue;
929 if (strcmp(word[2], "login"))
930 continue;
931 if (strcmp(word[4], "password") && strcmp(word[4], "password-hash"))
932 continue;
933
934 // Treat the host name found in file as a regular expression
935 // with '*' as a wild card
936 TString href(word[1]);
937 href.ReplaceAll("*",".*");
938 TRegexp rg(href);
939 if (remote.Index(rg) != kNPOS) {
940 if (user == "") {
941 user = word[3];
942 passwd = word[5];
943 if (!strcmp(word[4], "password-hash"))
944 pwhash = kTRUE;
945 result = kTRUE;
946 break;
947 } else {
948 if (!strcmp(word[3], user.Data())) {
949 passwd = word[5];
950 if (!strcmp(word[4], "password-hash"))
951 pwhash = kTRUE;
952 result = kTRUE;
953 break;
954 }
955 }
956 }
957 }
958 fclose(fd);
959 } else
960 Warning("CheckNetrc",
961 "file %s exists but has not 0600 permission", net);
962 }
963
964 if (first && !result) {
965 TString temp_net = ".netrc";
967 first = kFALSE;
968 goto again;
969 }
970
971 return result;
972 }
973
974////////////////////////////////////////////////////////////////////////////////
975/// Static method returning the global user.
976
978{
979 return fgUser;
980}
981
982////////////////////////////////////////////////////////////////////////////////
983/// Static method returning the global password hash flag.
984
989
990////////////////////////////////////////////////////////////////////////////////
991/// Static method returning the global SRP password flag.
992
997
998////////////////////////////////////////////////////////////////////////////////
999/// Static method returning default expiring date for new validity contexts
1000
1005
1006////////////////////////////////////////////////////////////////////////////////
1007/// Static method returning the default user information.
1008
1010{
1011 return fgDefaultUser;
1012}
1013
1014////////////////////////////////////////////////////////////////////////////////
1015/// Static method returning the principal to be used to init Krb5 tickets.
1016
1018{
1019 ::Error("Krb5Auth", "Kerberos5 is no longer supported by ROOT");
1020 return nullptr;
1021}
1022
1023////////////////////////////////////////////////////////////////////////////////
1024/// Static method returning the authentication reuse settings.
1025
1027{
1028 return fgAuthReUse;
1029}
1030
1031////////////////////////////////////////////////////////////////////////////////
1032/// Static method returning the prompt user settings.
1033
1035{
1036 return fgPromptUser;
1037}
1038
1039////////////////////////////////////////////////////////////////////////////////
1040/// Static method returning the method corresponding to idx.
1041
1043{
1045
1046 if (idx < 0 || idx > kMAXSEC-1) {
1047 ::Error("Authenticate::GetAuthMethod", "idx out of bounds (%d)", idx);
1048 idx = 0;
1049 }
1050 return fgAuthMeth[idx];
1051}
1052
1053////////////////////////////////////////////////////////////////////////////////
1054/// Static method returning the method index (which can be used to find
1055/// the method in GetAuthMethod()). Returns -1 in case meth is not found.
1056
1058{
1060
1061 if (meth && meth[0]) {
1062 for (Int_t i = 0; i < kMAXSEC; i++) {
1063 if (!fgAuthMeth[i].CompareTo(meth, TString::kIgnoreCase))
1064 return i;
1065 }
1066 }
1067
1068 return -1;
1069}
1070
1071////////////////////////////////////////////////////////////////////////////////
1072/// Static method to prompt for the user name to be used for authentication
1073/// to rootd. User is asked to type user name.
1074/// Returns user name (which must be deleted by caller) or 0.
1075/// If non-interactive run returns default user.
1076
1078{
1080
1081 const char *user;
1082 if (fgDefaultUser != "")
1083 user = fgDefaultUser;
1084 else
1085 user = gSystem->Getenv("USER");
1086#ifdef R__WIN32
1087 if (!user)
1088 user = gSystem->Getenv("USERNAME");
1089#endif
1090 if (isatty(0) == 0 || isatty(1) == 0) {
1091 ::Warning("TAuthenticate::PromptUser",
1092 "not tty: cannot prompt for user, returning default");
1093 if (strlen(user))
1094 return StrDup(user);
1095 else
1096 return StrDup("None");
1097 }
1098
1099 const char *usrIn = Getline(Form("Name (%s:%s): ", remote, user));
1100 if (usrIn[0]) {
1101 TString usr(usrIn);
1102 usr.Remove(usr.Length() - 1); // get rid of \n
1103 if (!usr.IsNull())
1104 return StrDup(usr);
1105 else
1106 return StrDup(user);
1107 }
1108 return 0;
1109}
1110
1111////////////////////////////////////////////////////////////////////////////////
1112/// Static method to prompt for the user's passwd to be used for
1113/// authentication to rootd. Uses non-echoing command line
1114/// to get passwd. Returns passwd (which must de deleted by caller) or 0.
1115/// If non-interactive run returns -1
1116
1118{
1119 if (isatty(0) == 0 || isatty(1) == 0) {
1120 ::Warning("TAuthenticate::PromptPasswd",
1121 "not tty: cannot prompt for passwd, returning -1");
1122 static char noint[4] = {"-1"};
1123 return StrDup(noint);
1124 }
1125
1126 char buf[128] = "";
1127 const char *pw = buf;
1128 // Get the plugin for the passwd dialog box, if needed
1129 if (!gROOT->IsBatch() && (fgPasswdDialog == (TPluginHandler *)(-1)) &&
1130 gEnv->GetValue("Auth.UsePasswdDialogBox", 1) == 1) {
1131 if ((fgPasswdDialog =
1132 gROOT->GetPluginManager()->FindHandler("TGPasswdDialog"))) {
1133 if (fgPasswdDialog->LoadPlugin() == -1) {
1134 fgPasswdDialog = 0;
1135 ::Warning("TAuthenticate",
1136 "could not load plugin for the password dialog box");
1137 }
1138 }
1139 }
1140 if (fgPasswdDialog && (fgPasswdDialog != (TPluginHandler *)(-1))) {
1141
1142 // Use graphic dialog
1143 fgPasswdDialog->ExecPlugin(3, prompt, buf, 128);
1144
1145 // Wait until the user is done
1146 while (gROOT->IsInterrupted())
1148
1149 } else {
1150 Gl_config("noecho", 1);
1151 pw = Getline(prompt);
1152 Gl_config("noecho", 0);
1153 }
1154
1155 // Final checks
1156 if (pw[0]) {
1157 TString spw(pw);
1158 if (spw.EndsWith("\n"))
1159 spw.Remove(spw.Length() - 1); // get rid of \n
1160 char *rpw = StrDup(spw.Data());
1161 return rpw;
1162 }
1163 return 0;
1164}
1165
1166////////////////////////////////////////////////////////////////////////////////
1167/// Static method returning the globus authorization hook (no longer supported)
1168
1173
1174////////////////////////////////////////////////////////////////////////////////
1175/// Static method returning the RSA public keys.
1176
1178{
1179 key = (key >= 0 && key <= 1) ? key : 0;
1180 return fgRSAPubExport[key].keys;
1181}
1182
1183////////////////////////////////////////////////////////////////////////////////
1184/// Static method returning the RSA initialization flag.
1185
1187{
1188 return fgRSAInit;
1189}
1190
1191////////////////////////////////////////////////////////////////////////////////
1192/// Static method setting the default type of RSA key.
1193
1195{
1196 if (key >= 0 && key <= 1)
1197 fgRSAKey = key;
1198}
1199
1200////////////////////////////////////////////////////////////////////////////////
1201/// Static method setting RSA initialization flag.
1202
1204{
1205 fgRSAInit = init;
1206}
1207
1208////////////////////////////////////////////////////////////////////////////////
1209/// Static method returning the list with authentication details.
1210
1212{
1214
1215 if (!fgAuthInfo)
1216 fgAuthInfo = new TList;
1217 return fgAuthInfo;
1218}
1219
1220////////////////////////////////////////////////////////////////////////////////
1221/// Print error string depending on error code.
1222
1224{
1226
1227 // Make sure it is in range
1228 err = (err < kErrError) ? ((err > -1) ? err : -1) : kErrError;
1229
1230 Int_t erc = err;
1232 TString lasterr = "";
1233 if (err == -1) {
1234 forceprint = kTRUE;
1235 erc = fgLastError;
1236 lasterr = "(last error only; re-run with gDebug > 0 for more details)";
1237 }
1238
1239 if (erc > -1)
1240 if (gDebug > 0 || forceprint) {
1241 if (gRootdErrStr[erc])
1242 ::Error(Form("TAuthenticate::%s", where), "%s %s",
1243 gRootdErrStr[erc], lasterr.Data());
1244 else
1245 ::Error(Form("TAuthenticate::%s", where),
1246 "unknown error code: server must be running a newer ROOT version %s",
1247 lasterr.Data());
1248 }
1249
1250 // Update last error code
1251 fgLastError = err;
1252}
1253
1254////////////////////////////////////////////////////////////////////////////////
1255/// Set global user name to be used for authentication to rootd.
1256
1258{
1260
1261 if (fgUser != "")
1262 fgUser = "";
1263
1264 if (user && user[0])
1265 fgUser = user;
1266}
1267
1268////////////////////////////////////////////////////////////////////////////////
1269/// Set global passwd to be used for authentication to rootd.
1270
1272{
1274
1275 if (fgPasswd != "")
1276 fgPasswd = "";
1277
1278 if (passwd && passwd[0])
1279 fgPasswd = passwd;
1280}
1281
1282////////////////////////////////////////////////////////////////////////////////
1283/// Set global passwd hash flag to be used for authentication to rootd.
1284
1289
1290////////////////////////////////////////////////////////////////////////////////
1291/// Set global SRP passwd flag to be used for authentication to rootd.
1292
1294{
1295 ::Error("SetGlobalSRPPwd", "SRP no longer supported by ROOT");
1296}
1297
1298////////////////////////////////////////////////////////////////////////////////
1299/// Set default expiring date for new validity contexts
1300
1305
1306////////////////////////////////////////////////////////////////////////////////
1307/// Set default user name.
1308
1310{
1311 if (fgDefaultUser != "")
1312 fgDefaultUser = "";
1313
1314 if (defaultuser && defaultuser[0])
1315 fgDefaultUser = defaultuser;
1316}
1317
1318////////////////////////////////////////////////////////////////////////////////
1319/// Set timeout (active if > 0)
1320
1322{
1323 fgAuthTO = (to <= 0) ? -1 : to;
1324}
1325
1326////////////////////////////////////////////////////////////////////////////////
1327/// Set global AuthReUse flag
1328
1333
1334////////////////////////////////////////////////////////////////////////////////
1335/// Set global PromptUser flag
1336
1341
1342////////////////////////////////////////////////////////////////////////////////
1343/// Set secure authorization function.
1344
1346{
1347 fgSecAuthHook = func;
1348}
1349
1350////////////////////////////////////////////////////////////////////////////////
1351/// Set kerberos5 authorization function. Automatically called when
1352/// libKrb5Auth is loaded.
1353
1355{
1356 ::Error("Krb5Auth", "Kerberos5 is no longer supported by ROOT");
1357}
1358
1359////////////////////////////////////////////////////////////////////////////////
1360/// Set Globus authorization function. Automatically called when
1361/// libGlobusAuth is loaded.
1362
1364{
1365 ::Error("GlobusAuth", "Globus is no longer supported by ROOT");
1366}
1367
1368////////////////////////////////////////////////////////////////////////////////
1369/// SSH client authentication code (no longer supported)
1370
1372{
1373 ::Error("SshAuth", "SSH is no longer supported by ROOT");
1374 return 1;
1375}
1376
1377////////////////////////////////////////////////////////////////////////////////
1378/// Method returning the user to be used for the ssh login (no longer supported)
1379
1381{
1382 ::Error("GetSshUser", "SSH is no longer supported by ROOT");
1383 return nullptr;
1384}
1385
1386////////////////////////////////////////////////////////////////////////////////
1387/// Check if 'host' matches 'href':
1388/// this means either equal or "containing" it, even with wild cards *
1389/// in the first field (in the case 'href' is a name, ie not IP address)
1390/// Returns kTRUE if the two matches.
1391
1393{
1395
1397
1398 // Both strings should have been defined
1399 if (!host || !href)
1400 return kFALSE;
1401
1402 // 'href' == '*' indicates any 'host' ...
1403 if (!strcmp(href,"*"))
1404 return kTRUE;
1405
1406 // If 'href' contains at a letter or an hyphen it is assumed to be
1407 // a host name. Otherwise a name.
1408 // Check also for wild cards
1409 Bool_t name = kFALSE;
1410 TRegexp rename("[+a-zA-Z]");
1411 Int_t len;
1412 if (rename.Index(href,&len) != -1 || strstr(href,"-"))
1413 name = kTRUE;
1414
1415 // Check also for wild cards
1416 Bool_t wild = kFALSE;
1417 if (strstr(href,"*"))
1418 wild = kTRUE;
1419
1420 // Now build the regular expression for final checking
1422
1423 // host to check
1424 TString theHost(host);
1425 if (!name) {
1427 theHost = addr.GetHostAddress();
1428 if (gDebug > 2)
1429 ::Info("TAuthenticate::CheckHost", "checking host IP: %s", theHost.Data());
1430 }
1431
1432 // Check 'host' against 'rehost'
1433 Ssiz_t pos = rehost.Index(theHost,&len);
1434 if (pos == -1)
1435 retval = kFALSE;
1436
1437 // If IP and no wilds, it should match either
1438 // the beginning or the end of the string
1439 if (!wild) {
1440 if (pos > 0 && pos != (Ssiz_t)(theHost.Length()-strlen(href)))
1441 retval = kFALSE;
1442 }
1443
1444 return retval;
1445}
1446
1447////////////////////////////////////////////////////////////////////////////////
1448/// RFIO authentication (no longer supported)
1449
1451{
1452 ::Error("RfioAuth", "RfioAuth is no longer supported by ROOT");
1453 return -1;
1454}
1455
1456////////////////////////////////////////////////////////////////////////////////
1457/// UsrPwd client authentication code.
1458/// Returns 0 in case authentication failed
1459/// 1 in case of success
1460
1462{
1464
1465 if (gDebug > 2)
1466 Info("ClearAuth", "enter: user: %s (passwd hashed?: %d)",
1467 user.Data(),(Int_t)pwdhash);
1468
1469 Int_t reuse = fgAuthReUse;
1470 Int_t prompt = fgPromptUser;
1471 Int_t cryptopt = fgUsrPwdCrypt;
1472 Int_t needsalt = 1;
1473 if (pwdhash)
1474 needsalt = 0;
1475 fDetails = TString::Format("pt:%d ru:%d cp:%d us:",
1476 fgPromptUser, fgAuthReUse, fgUsrPwdCrypt) + user;
1477 if (gDebug > 2)
1478 Info("ClearAuth", "ru:%d pt:%d cp:%d ns:%d rk:%d",
1479 fgAuthReUse,fgPromptUser,fgUsrPwdCrypt,needsalt,fgRSAKey);
1480#ifdef R__WIN32
1481 needsalt = 0;
1482#endif
1483 Int_t stat, kind;
1484
1485 if (fVersion > 1) {
1486
1487 //
1488 // New protocol
1489 //
1490 Int_t anon = 0;
1491 TString salt = "";
1492 TString pashash = "";
1493
1494 // Get effective user (fro remote checks in $HOME/.rhosts)
1497 if (pw) {
1498 effUser = TString(pw->fUser);
1499 delete pw;
1500 } else
1501 effUser = user;
1502
1503 // Create options string
1504 int opt = (reuse * kAUTH_REUSE_MSK) + (cryptopt * kAUTH_CRYPT_MSK) +
1505 (needsalt * kAUTH_SSALT_MSK) + (fRSAKey * kAUTH_RSATY_MSK);
1506 TString options;
1507 options.Form("%d %ld %s %ld %s", opt,
1508 (Long_t)user.Length(), user.Data(),
1509 (Long_t)effUser.Length(), effUser.Data());
1510
1511 // Check established authentications
1512 kind = kROOTD_USER;
1513 stat = reuse;
1514 Int_t rc = 0;
1515 if ((rc = AuthExists(user, (Int_t) TAuthenticate::kClear, options,
1516 &kind, &stat, &StdCheckSecCtx)) == 1) {
1517 // A valid authentication exists: we are done ...
1518 return 1;
1519 }
1520 if (rc == -2) {
1521 return rc;
1522 }
1523 if (stat == kErrNotAllowed && kind == kROOTD_ERR) {
1524 return 0;
1525 }
1526
1527 if (kind == kROOTD_AUTH && stat == -1) {
1528 if (gDebug > 3)
1529 Info("ClearAuth", "anonymous user");
1530 anon = 1;
1531 cryptopt = 0;
1532 reuse = 0;
1533 needsalt = 0;
1534 }
1535
1536 // The random tag in hex representation
1537 // Protection against reply attacks
1538 char ctag[11] = {0};
1539 if (anon == 0 && cryptopt == 1) {
1540
1541 // Check that we got the right thing ..
1542 if (kind != kROOTD_RSAKEY || stat < 1 || stat > 2 ) {
1543 // Check for errors
1544 if (kind != kROOTD_ERR) {
1545 Warning("ClearAuth",
1546 "problems recvn RSA key flag: got message %d, flag: %d",
1547 kind, stat);
1548 }
1549 return 0;
1550 }
1551 if (gDebug > 3)
1552 Info("ClearAuth", "get key request ...");
1553
1554 // Save type of key
1555 fRSAKey = stat - 1;
1556
1557 // Send the key securely
1558 if (SendRSAPublicKey(fSocket,fRSAKey) < 0)
1559 return 0;
1560
1561 int slen = 0;
1562 if (needsalt) {
1563 // Receive password salt
1564 char *tmpsalt = 0;
1565 if ((slen = SecureRecv(fSocket, 1, fRSAKey, &tmpsalt)) == -1) {
1566 Warning("ClearAuth", "problems secure-receiving salt -"
1567 " may result in corrupted salt");
1568 Warning("ClearAuth", "switch off reuse for this session");
1569 delete [] tmpsalt;
1570 return 0;
1571 }
1572 if (slen) {
1573 // Extract random tag, if there
1574 if (slen > 9) {
1575 int ltmp = slen;
1576 while (ltmp && tmpsalt[ltmp-1] != '#') ltmp--;
1577 if (ltmp) {
1578 if (tmpsalt[ltmp-1] == '#' &&
1579 tmpsalt[ltmp-10] == '#') {
1580 strlcpy(ctag,&tmpsalt[ltmp-10],11);
1581 // We drop the random tag
1582 ltmp -= 10;
1583 tmpsalt[ltmp] = 0;
1584 // Update salt length
1585 slen -= 10;
1586 }
1587 }
1588 if (!tmpsalt[0]) {
1589 // No salt left
1590 needsalt = 0;
1591 slen = 0;
1592 }
1593 }
1594 if (slen)
1595 salt = TString(tmpsalt);
1596 }
1597 delete [] tmpsalt;
1598 if (gDebug > 2)
1599 Info("ClearAuth", "got salt: '%s' (len: %d)", salt.Data(), slen);
1600 } else {
1601 if (gDebug > 2)
1602 Info("ClearAuth", "Salt not required");
1603 char *tmptag = 0;
1604 if (SecureRecv(fSocket, 1, fRSAKey, &tmptag) == -1) {
1605 Warning("ClearAuth", "problems secure-receiving rndmtag -"
1606 " may result in corrupted rndmtag");
1607 }
1608 if (tmptag) {
1609 strlcpy(ctag, tmptag, 11);
1610 delete [] tmptag;
1611 }
1612 }
1613 // We may not have got a salt (if the server may not access it
1614 // or if it needs the full password, like for AFS ...)
1615 if (!slen)
1616 needsalt = 0;
1617 }
1618 // Now get the password either from prompt or from memory, if saved already
1619 if (anon == 1) {
1620
1621 if (fgPasswd.Contains("@")) {
1622 // Anonymous like login with user chosen passwd ...
1623 passwd = fgPasswd;
1624 } else {
1625 // Anonymous like login with automatic passwd generation ...
1627 pw = gSystem->GetUserInfo();
1628 if (pw) {
1629 char *u = StrDup(pw->fUser);
1630 localuser = u;
1631 delete[] u;
1632 }
1633 delete pw;
1634 static TString localFQDN;
1635 if (localFQDN == "") {
1637 if (addr.IsValid())
1638 localFQDN = addr.GetHostName();
1639 }
1640 passwd.Form("%s@%s", localuser.Data(), localFQDN.Data());
1641 if (gDebug > 2)
1642 Info("ClearAuth",
1643 "automatically generated anonymous passwd: %s",
1644 passwd.Data());
1645 }
1646
1647 } else {
1648
1649 if (prompt == 1 || pashash.Length() == 0) {
1650
1651 if (passwd == "") {
1652 TString xp;
1653 xp.Form("%s@%s password: ", user.Data(),fRemote.Data());
1654 char *pwd = PromptPasswd(xp);
1655 passwd = TString(pwd);
1656 delete [] pwd;
1657 if (passwd == "") {
1658 Error("ClearAuth", "password not set");
1659 fSocket->Send("-1", kROOTD_PASS); // Needs this for consistency
1660 return 0;
1661 }
1662 }
1663 if (needsalt && !pwdhash) {
1664#ifndef R__WIN32
1666 if (!pashash.BeginsWith(salt)) {
1667 // not the right version of the crypt function:
1668 // do not send hash
1669 pashash = passwd;
1670 }
1671#else
1672 pashash = passwd;
1673#endif
1674 } else {
1675 pashash = passwd;
1676 }
1677 }
1678
1679 }
1680
1681 // Store password for later use
1682 fgUser = fUser;
1683 fgPwHash = kFALSE;
1684 fPwHash = kFALSE;
1685 fgPasswd = passwd;
1686 fPasswd = passwd;
1687
1688 // Send it to server
1689 if (anon == 0 && cryptopt == 1) {
1690
1691 // Needs to send this for consistency
1692 if (fSocket->Send("\0", kROOTD_PASS) < 0)
1693 return 0;
1694
1695 // Add the random tag received from the server
1696 // (if any); makes packets non re-usable
1697 if (strlen(ctag))
1698 pashash += ctag;
1699
1700 if (SecureSend(fSocket, 1, fRSAKey, pashash.Data()) == -1) {
1701 Warning("ClearAuth", "problems secure-sending pass hash"
1702 " - may result in authentication failure");
1703 return 0;
1704 }
1705 } else {
1706
1707 // Standard technique: invert passwd
1708 if (passwd != "") {
1709 for (int i = 0; i < passwd.Length(); i++) {
1710 char inv = ~passwd(i);
1711 passwd.Replace(i, 1, inv);
1712 }
1713 }
1714 if (fSocket->Send(passwd.Data(), kROOTD_PASS) < 0)
1715 return 0;
1716 }
1717
1718 Int_t nrec = 0;
1719 // Receive username used for login
1720 if ((nrec = fSocket->Recv(stat, kind)) < 0 ) // returns user
1721 return 0;
1722 if (gDebug > 3)
1723 Info("ClearAuth", "after kROOTD_PASS: kind= %d, stat= %d", kind,
1724 stat);
1725
1726 // Check for errors
1727 if (kind == kROOTD_ERR) {
1728 AuthError("ClearAuth", stat);
1729 fgPasswd = "";
1730 return 0;
1731 }
1732
1733 if (kind != kROOTD_PASS || stat < 1)
1734 Warning("ClearAuth",
1735 "problems recvn (user,offset) length (%d:%d bytes:%d)",
1736 kind, stat, nrec);
1737
1738 // Get user and offset
1739 char answer[256];
1740 int reclen = (stat+1 > 256) ? 256 : stat+1;
1741 if ((nrec = fSocket->Recv(answer, reclen, kind)) < 0)
1742 return 0;
1743 if (kind != kMESS_STRING)
1744 Warning("ClearAuth",
1745 "username and offset not received (%d:%d)", kind,
1746 nrec);
1747
1748 // Parse answer
1749 char lUser[128];
1750 Int_t offset = -1;
1751 sscanf(answer, "%127s %d", lUser, &offset);
1752 if (gDebug > 3)
1753 Info("ClearAuth",
1754 "received from server: user: %s, offset: %d (%s)", lUser,
1755 offset, answer);
1756
1757 // Return username
1758 user = lUser;
1759
1760 char *token = 0;
1761 if (reuse == 1 && offset > -1) {
1762 // Receive token
1763 if (cryptopt == 1) {
1764 if (SecureRecv(fSocket, 1, fRSAKey, &token) == -1) {
1765 Warning("ClearAuth",
1766 "problems secure-receiving token -"
1767 " may result in corrupted token");
1768 return 0;
1769 }
1770 } else {
1771 Int_t tlen = 9;
1772 token = new char[tlen];
1773 if (fSocket->Recv(token, tlen, kind) < 0) {
1774 delete [] token;
1775 return 0;
1776 }
1777 if (kind != kMESS_STRING)
1778 Warning("ClearAuth", "token not received (%d:%d)", kind,
1779 nrec);
1780 // Invert token
1781 for (int i = 0; i < (int) strlen(token); i++) {
1782 token[i] = ~token[i];
1783 }
1784
1785 }
1786 if (gDebug > 3)
1787 Info("ClearAuth", "received from server: token: '%s' ",
1788 token);
1789 }
1790 TPwdCtx *pwdctx = new TPwdCtx(fPasswd,fPwHash);
1791 // Create SecContext object
1792 fSecContext = fHostAuth->CreateSecContext((const char *)lUser, fRemote,
1793 kClear, offset, fDetails, (const char *)token,
1794 fgExpDate, (void *)pwdctx, fRSAKey);
1795
1796 // Release allocated memory ...
1797 if (token)
1798 delete [] token;
1799
1800 // This from remote login
1801 if (fSocket->Recv(stat, kind) < 0)
1802 return 0;
1803
1804
1805 if (kind == kROOTD_AUTH && stat >= 1) {
1806 fgPasswd = "";
1807 if (kind == kROOTD_ERR)
1808 AuthError("ClearAuth", stat);
1809 return 0;
1810 }
1811
1812 } else {
1813
1814 // Old Protocol
1815
1816 // Send username
1817 if (fSocket->Send(user.Data(), kROOTD_USER) < 0)
1818 return 0;
1819
1820 // Get replay from server
1821 if (fSocket->Recv(stat, kind) < 0)
1822 return 0;
1823
1824 // This check should guarantee backward compatibility with a private
1825 // version of rootd used by CDF
1826 if (kind == kROOTD_AUTH && stat == 1) {
1827 fSecContext =
1828 fHostAuth->CreateSecContext(user,fRemote,kClear,-1,fDetails,0);
1829 return 1;
1830 }
1831
1832 if (kind == kROOTD_ERR) {
1833 TString server = "sockd";
1834 if (fProtocol.Contains("root"))
1835 server = "rootd";
1836 if (stat == kErrConnectionRefused) {
1837 if (gDebug > 0)
1838 Error("ClearAuth",
1839 "%s@%s does not accept connections from %s@%s",
1840 server.Data(),fRemote.Data(),
1841 fUser.Data(),gSystem->HostName());
1842 return -2;
1843 } else if (stat == kErrNotAllowed) {
1844 if (gDebug > 0)
1845 Error("ClearAuth",
1846 "%s@%s does not accept %s authentication from %s@%s",
1847 server.Data(),fRemote.Data(),
1848 TAuthenticate::fgAuthMeth[0].Data(),
1849 fUser.Data(),gSystem->HostName());
1850 } else
1851 AuthError("ClearAuth", stat);
1852 return 0;
1853 }
1854 // Prepare passwd to send
1855 badpass1:
1856 if (passwd == "") {
1857 TString xp;
1858 xp.Form("%s@%s password: ", user.Data(),fRemote.Data());
1859 char *p = PromptPasswd(xp);
1860 passwd = p;
1861 delete [] p;
1862 if (passwd == "")
1863 Error("ClearAuth", "password not set");
1864 }
1865 if (fUser == "anonymous" || fUser == "rootd") {
1866 if (!passwd.Contains("@")) {
1867 Warning("ClearAuth",
1868 "please use passwd of form: user@host.do.main");
1869 passwd = "";
1870 goto badpass1;
1871 }
1872 }
1873
1874 fgPasswd = passwd;
1875 fPasswd = passwd;
1876
1877 // Invert passwd
1878 if (passwd != "") {
1879 for (int i = 0; i < passwd.Length(); i++) {
1880 char inv = ~passwd(i);
1881 passwd.Replace(i, 1, inv);
1882 }
1883 }
1884 // Send it over the net
1885 if (fSocket->Send(passwd, kROOTD_PASS) < 0)
1886 return 0;
1887
1888 // Get result of attempt
1889 if (fSocket->Recv(stat, kind) < 0) // returns user
1890 return 0;
1891 if (gDebug > 3)
1892 Info("ClearAuth", "after kROOTD_PASS: kind= %d, stat= %d", kind,
1893 stat);
1894
1895 if (kind == kROOTD_AUTH && stat == 1) {
1896 fSecContext =
1897 fHostAuth->CreateSecContext(user,fRemote,kClear,-1,fDetails,0);
1898 return 1;
1899 } else {
1900 if (kind == kROOTD_ERR)
1901 AuthError("ClearAuth", stat);
1902 return 0;
1903 }
1904 }
1905 return 0;
1906}
1907
1908////////////////////////////////////////////////////////////////////////////////
1909/// Sets fUser=user and search fgAuthInfo for the entry pertaining to
1910/// (host,user), setting fHostAuth accordingly.
1911/// If no entry is found fHostAuth is not changed
1912
1914ROOT::Deprecated::TAuthenticate::GetHostAuth(const char *host, const char *user, Option_t */*opt*/, Int_t *exact)
1915{
1916 if (exact)
1917 *exact = 0;
1918
1919 if (gDebug > 2)
1920 ::Info("TAuthenticate::GetHostAuth", "enter ... %s ... %s", host, user);
1921
1922 // Strip off the servertype, if any
1923 Int_t srvtyp = -1;
1924 TString hostname = host;
1925 if (hostname.Contains(":")) {
1926 char *ps = (char *)strstr(host,":");
1927 if (ps)
1928 srvtyp = atoi(ps+1);
1929 hostname.Remove(hostname.Index(":"));
1930 }
1932 if (strncmp(host,"default",7) && !hostFQDN.Contains("*")) {
1934 if (addr.IsValid())
1935 hostFQDN = addr.GetHostName();
1936 }
1937 TString usr = user;
1938 if (!usr.Length())
1939 usr = "*";
1940 THostAuth *rHA = 0;
1941
1942 // Check list of auth info for already loaded info about this host
1943 TIter *next = new TIter(GetAuthInfo());
1944
1945 THostAuth *ai;
1948 while ((ai = (THostAuth *) (*next)())) {
1949 if (gDebug > 3)
1950 ai->Print("Authenticate::GetHostAuth");
1951
1952 // server
1953 if (!(serverOK = (ai->GetServer() == -1) ||
1954 (ai->GetServer() == srvtyp)))
1955 continue;
1956
1957 // Use default entry if existing and nothing more specific is found
1958 if (!strcmp(ai->GetHost(),"default") && serverOK && notFound)
1959 rHA = ai;
1960
1961 // Check
1962 if (CheckHost(hostFQDN,ai->GetHost()) &&
1963 CheckHost(usr,ai->GetUser()) && serverOK) {
1964 rHA = ai;
1965 notFound = kFALSE;
1966 }
1967
1968 if (hostFQDN == ai->GetHost() &&
1969 usr == ai->GetUser() && srvtyp == ai->GetServer() ) {
1970 rHA = ai;
1971 if (exact)
1972 *exact = 1;
1973 break;
1974 }
1975 }
1976 SafeDelete(next);
1977 return rHA;
1978}
1979
1980////////////////////////////////////////////////////////////////////////////////
1981/// Checks if a THostAuth with exact match for {host,user} exists
1982/// in the fgAuthInfo list
1983/// Returns pointer to it or 0
1984
1986ROOT::Deprecated::TAuthenticate::HasHostAuth(const char *host, const char *user, Option_t */*opt*/)
1987{
1988 if (gDebug > 2)
1989 ::Info("TAuthenticate::HasHostAuth", "enter ... %s ... %s", host, user);
1990
1991 // Strip off the servertype, if any
1992 Int_t srvtyp = -1;
1993 TString hostFQDN = host;
1994 if (hostFQDN.Contains(":")) {
1995 char *ps = (char *)strstr(host,":");
1996 if (ps)
1997 srvtyp = atoi(ps+1);
1998 hostFQDN.Remove(hostFQDN.Index(":"));
1999 }
2000 if (strncmp(host,"default",7) && !hostFQDN.Contains("*")) {
2002 if (addr.IsValid())
2003 hostFQDN = addr.GetHostName();
2004 }
2005
2006 TIter *next = new TIter(GetAuthInfo());
2007 THostAuth *ai;
2008 while ((ai = (THostAuth *) (*next)())) {
2009
2010 if (hostFQDN == ai->GetHost() &&
2011 !strcmp(user, ai->GetUser()) && srvtyp == ai->GetServer()) {
2012 SafeDelete(next);
2013 return ai;
2014 }
2015 }
2016 SafeDelete(next);
2017 return 0;
2018}
2019
2020////////////////////////////////////////////////////////////////////////////////
2021/// Expands include directives found in fexp files
2022/// The expanded, temporary file, is pointed to by 'ftmp'
2023/// and should be already open. To be called recursively.
2024
2026{
2027 FILE *fin;
2028 char line[kMAXPATHLEN];
2029 char cinc[20], fileinc[kMAXPATHLEN];
2030
2031 if (gDebug > 2)
2032 ::Info("TAuthenticate::FileExpand", "enter ... '%s' ... 0x%zx", fexp, (size_t)ftmp);
2033
2034 fin = fopen(fexp, "r");
2035 if (fin == 0)
2036 return;
2037
2038 while (fgets(line, sizeof(line), fin) != 0) {
2039 // Skip comment lines
2040 if (line[0] == '#')
2041 continue;
2042 if (line[strlen(line) - 1] == '\n')
2043 line[strlen(line) - 1] = '\0';
2044 if (gDebug > 2)
2045 ::Info("TAuthenticate::FileExpand", "read line ... '%s'", line);
2046 int nw = sscanf(line, "%19s %8191s", cinc, fileinc);
2047 if (nw < 1)
2048 continue; // Not enough info in this line
2049 if (strcmp(cinc, "include") != 0) {
2050 // copy line in temporary file
2051 fprintf(ftmp, "%s\n", line);
2052 } else {
2053
2054 // Drop quotes or double quotes, if any
2055 TString ln(line);
2056 ln.ReplaceAll("\"",1,"",0);
2057 ln.ReplaceAll("'",1,"",0);
2058 sscanf(ln.Data(), "%19s %8191s", cinc, fileinc);
2059
2060 // support environment directories ...
2061 if (fileinc[0] == '$') {
2064 if (edir.Contains("/")) {
2065 edir.Remove(edir.Index("/"));
2066 edir.Remove(0,1);
2067 if (gSystem->Getenv(edir.Data())) {
2068 finc.Remove(0,1);
2069 finc.ReplaceAll(edir.Data(),gSystem->Getenv(edir.Data()));
2070 fileinc[0] = '\0';
2072 fileinc[kMAXPATHLEN-1] = '\0';
2073 }
2074 }
2075 }
2076
2077 // open (expand) file in temporary file ...
2078 if (fileinc[0] == '~') {
2079 // needs to expand
2080 int flen =
2082 char *ffull = new char[flen];
2083 snprintf(ffull, flen, "%s/%s", gSystem->HomeDirectory(), fileinc + 1);
2085 delete [] ffull;
2086 }
2087 // Check if file exist and can be read ... ignore if not ...
2089 FileExpand(fileinc, ftmp);
2090 } else {
2091 ::Warning("TAuthenticate::FileExpand",
2092 "file specified by 'include' cannot be open or read (%s)",
2093 fileinc);
2094 }
2095 }
2096 }
2097 fclose(fin);
2098}
2099
2100////////////////////////////////////////////////////////////////////////////////
2101/// Determine default authentication details for method 'sec' and user 'usr'.
2102/// Checks .rootrc family files. Returned string must be deleted by the user.
2103
2105{
2106 char temp[kMAXPATHLEN] = { 0 };
2107 const char copt[2][5] = { "no", "yes" };
2108
2109 if (gDebug > 2)
2110 ::Info("TAuthenticate::GetDefaultDetails",
2111 "enter ... %d ...pt:%d ... '%s'", sec, opt, usr);
2112
2113 if (opt < 0 || opt > 1)
2114 opt = 1;
2115
2116 // UsrPwd
2117 if (sec == TAuthenticate::kClear) {
2118 if (!usr[0] || !strncmp(usr,"*",1))
2119 usr = gEnv->GetValue("UsrPwd.Login", "");
2120 snprintf(temp, kMAXPATHLEN, "pt:%s ru:%s cp:%s us:%s",
2121 gEnv->GetValue("UsrPwd.LoginPrompt", copt[opt]),
2122 gEnv->GetValue("UsrPwd.ReUse", "1"),
2123 gEnv->GetValue("UsrPwd.Crypt", "1"), usr);
2124 }
2125
2126 if (gDebug > 2)
2127 ::Info("TAuthenticate::GetDefaultDetails", "returning ... %s", temp);
2128
2129 return StrDup(temp);
2130}
2131
2132////////////////////////////////////////////////////////////////////////////////
2133/// Remove THostAuth instance from the list
2134
2136{
2137 GetAuthInfo()->Remove(ha);
2138 // ... destroy it
2139 delete ha;
2140}
2141
2142////////////////////////////////////////////////////////////////////////////////
2143/// Print info about the authentication sector.
2144/// If 'opt' contains 's' or 'S' prints information about established TSecContext,
2145/// else prints information about THostAuth
2146
2148{
2149 TString sopt(opt);
2150
2151 if (sopt.Contains("s", TString::kIgnoreCase)) {
2152
2153 // Print established security contexts
2155 TSecContext *sc = 0;
2156 while ((sc = (TSecContext *)next()))
2157 sc->Print();
2158
2159 } else {
2160
2161 ::Info("::Print", " +--------------------------- BEGIN --------------------------------+");
2162 ::Info("::Print", " + +");
2163 ::Info("::Print", " + List fgAuthInfo has %4d members +",
2164 GetAuthInfo()->GetSize());
2165 ::Info("::Print", " + +");
2166 ::Info("::Print", " +------------------------------------------------------------------+");
2167 TIter next(GetAuthInfo());
2168 THostAuth *ai;
2169 while ((ai = (THostAuth *)next())) {
2170 ai->Print();
2171 ai->PrintEstablished();
2172 }
2173 ::Info("::Print", " +---------------------------- END ---------------------------------+");
2174 }
2175}
2176
2177////////////////////////////////////////////////////////////////////////////////
2178/// Check if we have a valid established sec context in memory
2179/// Retrieves relevant info and negotiates with server.
2180/// options = "Opt,strlen(username),username.Data()"
2181/// message = kROOTD_USER, ...
2182
2184 Int_t *message, Int_t *rflag,
2185 CheckSecCtx_t checksecctx)
2186{
2187 // Welcome message, if requested ...
2188 if (gDebug > 2)
2189 Info("AuthExists","%d: enter: msg: %d options: '%s'",
2190 method,*message, options);
2191
2192 // Look for an existing security context matching this request
2194
2195 // First in the local list
2196 TIter next(fHostAuth->Established());
2198 while ((secctx = (TRootSecContext *)next())) {
2199 if (secctx->GetMethod() == method) {
2200 if (fRemote == secctx->GetHost()) {
2201 if (checksecctx &&
2202 (*checksecctx)(username,secctx) == 1)
2203 break;
2204 }
2205 }
2206 }
2207
2208 // If nothing found, try the all list
2209 if (!secctx) {
2211 while ((secctx = (TRootSecContext *)next())) {
2212 if (secctx->GetMethod() == method) {
2213 if (fRemote == secctx->GetHost()) {
2214 if (checksecctx &&
2215 (*checksecctx)(username,secctx) == 1) {
2216 notHA = kTRUE;
2217 break;
2218 }
2219 }
2220 }
2221 }
2222 }
2223
2224 // If we have been given a valid sec context retrieve some info
2225 Int_t offset = -1;
2226 TString token;
2227 if (secctx) {
2228 offset = secctx->GetOffSet();
2229 token = secctx->GetToken();
2230 if (gDebug > 2)
2231 Info("AuthExists",
2232 "found valid TSecContext: offset: %d token: '%s'",
2233 offset, token.Data());
2234 }
2235
2236 // Prepare string to be sent to the server
2237 TString sstr;
2238 sstr.Form("%d %d %s", fgProcessID, offset, options);
2239
2240 // Send message
2241 if (fSocket->Send(sstr, *message) < 0)
2242 return -2;
2243
2244 Int_t reuse = *rflag;
2245 if (reuse == 1 && offset > -1) {
2246
2247 // Receive result of checking offset
2248 // But only for recent servers
2249 // NB: not backward compatible with dev version 4.00.02: switch
2250 // off 'reuse' for such servers to avoid hanging at this point.
2251 Int_t rproto = fSocket->GetRemoteProtocol();
2252 Bool_t oldsrv = ((fProtocol.BeginsWith("root") && rproto == 9));
2253 Int_t stat = 1, kind;
2254 if (!oldsrv) {
2255 if (fSocket->Recv(stat, kind) < 0)
2256 return -2;
2257 if (kind != kROOTD_AUTH)
2258 Warning("AuthExists","protocol error: expecting %d got %d"
2259 " (value: %d)",kROOTD_AUTH,kind,stat);
2260 }
2261
2262 if (stat > 0) {
2263 if (gDebug > 2)
2264 Info("AuthExists","offset OK");
2265
2266 Int_t rsaKey = secctx->GetRSAKey();
2267 if (gDebug > 2)
2268 Info("AuthExists", "key type: %d", rsaKey);
2269
2270 if (rsaKey > -1) {
2271
2272 // Recent servers send a random tag in stat
2273 // It has to be signed too
2274 if (stat > 1) {
2275 // Create hex from tag
2276 char tag[9] = {0};
2277 snprintf(tag, 9, "%08x",stat);
2278 // Add to token
2279 token += tag;
2280 }
2281
2282 // Send token encrypted
2283 if (SecureSend(fSocket, 1, rsaKey, token) == -1) {
2284 Warning("AuthExists", "problems secure-sending token %s",
2285 "- may trigger problems in proofing Id ");
2286 return -2;
2287 }
2288 } else {
2289 // Send inverted
2290 for (int i = 0; i < token.Length(); i++) {
2291 char inv = ~token(i);
2292 token.Replace(i, 1, inv);
2293 }
2294 if (fSocket->Send(token, kMESS_STRING) < 0)
2295 return -2;
2296 }
2297 } else {
2298 if (gDebug > 0)
2299 Info("AuthExists","offset not OK - rerun authentication");
2300 // If the sec context was not valid, deactivate it ...
2301 if (secctx)
2302 secctx->DeActivate("");
2303 }
2304 }
2305
2306 Int_t stat, kind;
2307 if (fSocket->Recv(stat, kind) < 0)
2308 return -2;
2309 if (gDebug > 3)
2310 Info("AuthExists","%d: after msg %d: kind= %d, stat= %d",
2311 method,*message, kind, stat);
2312
2313 // Return flags
2314 *message = kind;
2315 *rflag = stat;
2316
2317 if (kind == kROOTD_ERR) {
2318 TString server = "sockd";
2319 if (fSocket->GetServType() == TSocket::kROOTD)
2320 server = "rootd";
2321 if (stat == kErrConnectionRefused) {
2322 Error("AuthExists","%s@%s does not accept connections from %s@%s",
2323 server.Data(),fRemote.Data(),fUser.Data(),gSystem->HostName());
2324 return -2;
2325 } else if (stat == kErrNotAllowed) {
2326 if (gDebug > 0)
2327 Info("AuthExists",
2328 "%s@%s does not accept %s authentication from %s@%s",
2329 server.Data(),fRemote.Data(), fgAuthMeth[method].Data(),
2330 fUser.Data(),gSystem->HostName());
2331 } else
2332 AuthError("AuthExists", stat);
2333
2334 // If the sec context was not valid, deactivate it ...
2335 if (secctx)
2336 secctx->DeActivate("");
2337 return 0;
2338 }
2339
2340 if (kind == kROOTD_AUTH && stat >= 1) {
2341 if (!secctx)
2342 secctx =
2343 fHostAuth->CreateSecContext(fUser,fRemote,method,-stat,fDetails,0);
2344 if (gDebug > 3) {
2345 if (stat == 1)
2346 Info("AuthExists", "valid authentication exists");
2347 if (stat == 2)
2348 Info("AuthExists", "valid authentication exists: offset changed");
2349 if (stat == 3)
2350 Info("AuthExists", "remote access authorized by /etc/hosts.equiv");
2351 if (stat == 4)
2352 Info("AuthExists", "no authentication required remotely");
2353 }
2354
2355 if (stat == 2) {
2356 int newOffSet;
2357 // Receive new offset ...
2358 if (fSocket->Recv(newOffSet, kind) < 0)
2359 return -2;
2360 // ... and save it
2361 secctx->SetOffSet(newOffSet);
2362 }
2363
2364 fSecContext = secctx;
2365 // Add it to local list for later use (if not already there)
2366 if (notHA)
2367 fHostAuth->Established()->Add(secctx);
2368 return 1;
2369 }
2370 return 0;
2371}
2372
2373////////////////////////////////////////////////////////////////////////////////
2374/// Initialize random machine using seed from /dev/urandom
2375/// (or current time if /dev/urandom not available).
2376
2378{
2379 static Bool_t notinit = kTRUE;
2380
2381 if (notinit) {
2382 const char *randdev = "/dev/urandom";
2383 Int_t fd;
2384 UInt_t seed;
2385 if ((fd = open(randdev, O_RDONLY)) != -1) {
2386 if (gDebug > 2)
2387 ::Info("InitRandom", "taking seed from %s", randdev);
2388 if (read(fd, &seed, sizeof(seed)) != sizeof(seed))
2389 ::Warning("InitRandom", "could not read seed from %s", randdev);
2390 close(fd);
2391 } else {
2392 if (gDebug > 2)
2393 ::Info("InitRandom", "%s not available: using time()", randdev);
2394 seed = time(0); //better use times() + win32 equivalent
2395 }
2396 srand(seed);
2397 notinit = kFALSE;
2398 }
2399}
2400
2401////////////////////////////////////////////////////////////////////////////////
2402/// Generate a valid pair of private/public RSA keys to protect for
2403/// authentication token exchange
2404
2406{
2407 if (gDebug > 2)
2408 Info("GenRSAKeys", "enter");
2409
2410 if (fgRSAInit == 1) {
2411 if (gDebug > 2)
2412 Info("GenRSAKeys", "Keys prviously generated - return");
2413 }
2414
2415 // This is for dynamic loads ...
2416 TString lib = "libRsa";
2417
2418 // This is the local RSA implementation
2419 if (!TRSA_fun::RSA_genprim()) {
2420 char *p;
2421 if ((p = gSystem->DynamicPathName(lib, kTRUE))) {
2422 delete [] p;
2423 gSystem->Load(lib);
2424 }
2425 }
2426
2427 // Init random machine
2429
2430#ifdef R__SSL
2431 if (fgRSAKey == 1) {
2432 // Generate also the SSL key
2433 if (gDebug > 2)
2434 Info("GenRSAKeys","SSL: Generate Blowfish key");
2435
2436 // Init SSL ...
2438
2439 // ... and its error strings
2441
2442 // Load Ciphers
2444
2445 // Number of bits for key
2446 Int_t nbits = gEnv->GetValue("SSL.BFBits",256);
2447
2448 // Minimum is 128
2449 nbits = (nbits >= 128) ? nbits : 128;
2450
2451 // Max to limit size of buffers to 15912 (internal limitation)
2452 nbits = (nbits <= 15912) ? nbits : 15912;
2453
2454 // Closer Number of chars
2455 Int_t klen = nbits / 8 ;
2456
2457 // Init random engine
2458 char *rbuf = GetRandString(0,klen);
2460
2461 // This is what we export
2462 fgRSAPubExport[1].len = klen;
2463 fgRSAPubExport[1].keys = rbuf;
2464 if (gDebug > 2)
2465 Info("GenRSAKeys","SSL: BF key length: %d", fgRSAPubExport[1].len);
2466
2467 // Now set the key locally in BF form
2468 BF_set_key(&fgBFKey, klen, (const unsigned char *)rbuf);
2469 }
2470#endif
2471
2472 // Sometimes some bunch is not decrypted correctly
2473 // That's why we make retries to make sure that encryption/decryption
2474 // works as expected
2475 Bool_t notOk = 1;
2477 Int_t l_n = 0, l_d = 0;
2479#if R__RSADE
2480 Int_t l_e;
2481 char buf[rsa_STRLEN];
2482#endif
2483
2484 Int_t nAttempts = 0;
2486 Int_t thePrimeExp = kPRIMEEXP; // Prime probability = 1-0.5^thePrimeExp
2487 while (notOk && nAttempts < kMAXRSATRIES) {
2488
2489 nAttempts++;
2490 if (gDebug > 2 && nAttempts > 1) {
2491 Info("GenRSAKeys", "retry no. %d",nAttempts);
2492 srand(auth_rand());
2493 }
2494
2495 // Valid pair of primes
2498
2499 // Retry if equal
2500 Int_t nPrimes = 0;
2501 while (TRSA_fun::RSA_cmp()(&p1, &p2) == 0 && nPrimes < kMAXRSATRIES) {
2502 nPrimes++;
2503 if (gDebug > 2)
2504 Info("GenRSAKeys", "equal primes: regenerate (%d times)",nPrimes);
2505 srand(auth_rand());
2508 }
2509#if R__RSADEB
2510 if (gDebug > 3) {
2512 Info("GenRSAKeys", "local: p1: '%s' ", buf);
2514 Info("GenRSAKeys", "local: p2: '%s' ", buf);
2515 }
2516#endif
2517 // Generate keys
2518 if (TRSA_fun::RSA_genrsa()(p1, p2, &rsa_n, &rsa_e, &rsa_d)) {
2519 if (gDebug > 2 && nAttempts > 1)
2520 Info("GenRSAKeys"," genrsa: unable to generate keys (%d)",
2521 nAttempts);
2522 continue;
2523 }
2524
2525 // Get equivalent strings and determine their lengths
2527 l_n = strlen(buf_n);
2529#if R__RSADEB
2530 l_e = strlen(buf_e);
2531#endif
2533 l_d = strlen(buf_d);
2534
2535#if R__RSADEB
2536 if (gDebug > 3) {
2537 Info("GenRSAKeys", "local: n: '%s' length: %d", buf_n, l_n);
2538 Info("GenRSAKeys", "local: e: '%s' length: %d", buf_e, l_e);
2539 Info("GenRSAKeys", "local: d: '%s' length: %d", buf_d, l_d);
2540 }
2541#endif
2542 if (TRSA_fun::RSA_cmp()(&rsa_n, &rsa_e) <= 0)
2543 continue;
2544 if (TRSA_fun::RSA_cmp()(&rsa_n, &rsa_d) <= 0)
2545 continue;
2546
2547 // Now we try the keys
2548 char test[2 * rsa_STRLEN] = "ThisIsTheStringTest01203456-+/";
2549 Int_t lTes = 31;
2550 char *tdum = GetRandString(0, lTes - 1);
2551 strlcpy(test, tdum, lTes+1);
2552 delete [] tdum;
2553 char buf[2 * rsa_STRLEN];
2554 if (gDebug > 3)
2555 Info("GenRSAKeys", "local: test string: '%s' ", test);
2556
2557 // Private/Public
2558 strlcpy(buf, test, lTes+1);
2559
2560 // Try encryption with private key
2561 int lout = TRSA_fun::RSA_encode()(buf, lTes, rsa_n, rsa_e);
2562 if (gDebug > 3)
2563 Info("GenRSAKeys",
2564 "local: length of crypted string: %d bytes", lout);
2565
2566 // Try decryption with public key
2568 buf[lTes] = 0;
2569 if (gDebug > 3)
2570 Info("GenRSAKeys", "local: after private/public : '%s' ", buf);
2571
2572 if (strncmp(test, buf, lTes))
2573 continue;
2574
2575 // Public/Private
2576 strlcpy(buf, test, lTes+1);
2577
2578 // Try encryption with public key
2580 if (gDebug > 3)
2581 Info("GenRSAKeys", "local: length of crypted string: %d bytes ",
2582 lout);
2583
2584 // Try decryption with private key
2586 buf[lTes] = 0;
2587 if (gDebug > 3)
2588 Info("GenRSAKeys", "local: after public/private : '%s' ", buf);
2589
2590 if (strncmp(test, buf, lTes))
2591 continue;
2592
2593 notOk = 0;
2594 }
2595
2596 // Save Private key
2597 TRSA_fun::RSA_assign()(&fgRSAPriKey.n, &rsa_n);
2598 TRSA_fun::RSA_assign()(&fgRSAPriKey.e, &rsa_e);
2599
2600 // Save Public key
2601 TRSA_fun::RSA_assign()(&fgRSAPubKey.n, &rsa_n);
2602 TRSA_fun::RSA_assign()(&fgRSAPubKey.e, &rsa_d);
2603
2604#if R__RSADEB
2605 if (gDebug > 2) {
2606 // Determine their lengths
2607 Info("GenRSAKeys", "local: generated keys are:");
2608 Info("GenRSAKeys", "local: n: '%s' length: %d", buf_n, l_n);
2609 Info("GenRSAKeys", "local: e: '%s' length: %d", buf_e, l_e);
2610 Info("GenRSAKeys", "local: d: '%s' length: %d", buf_d, l_d);
2611 }
2612#endif
2613 // Export form
2614 if (fgRSAPubExport[0].keys) {
2615 delete [] fgRSAPubExport[0].keys;
2616 fgRSAPubExport[0].len = 0;
2617 }
2618 fgRSAPubExport[0].len = l_n + l_d + 4;
2619 fgRSAPubExport[0].keys = new char[fgRSAPubExport[0].len];
2620
2621 fgRSAPubExport[0].keys[0] = '#';
2622 memcpy(fgRSAPubExport[0].keys + 1, buf_n, l_n);
2623 fgRSAPubExport[0].keys[l_n + 1] = '#';
2624 memcpy(fgRSAPubExport[0].keys + l_n + 2, buf_d, l_d);
2625 fgRSAPubExport[0].keys[l_n + l_d + 2] = '#';
2626 fgRSAPubExport[0].keys[l_n + l_d + 3] = 0;
2627#if R__RSADEB
2628 if (gDebug > 2)
2629 Info("GenRSAKeys", "local: export pub: '%s'", fgRSAPubExport[0].keys);
2630#else
2631 if (gDebug > 2)
2632 Info("GenRSAKeys", "local: export pub length: %d bytes", fgRSAPubExport[0].len);
2633#endif
2634
2635 // Set availability flag
2636 fgRSAInit = 1;
2637
2638 return 0;
2639}
2640
2641////////////////////////////////////////////////////////////////////////////////
2642/// Allocates and fills a 0 terminated buffer of length len+1 with
2643/// len random characters.
2644/// Returns pointer to the buffer (to be deleted by the caller)
2645/// opt = 0 any non dangerous char
2646/// 1 letters and numbers (upper and lower case)
2647/// 2 hex characters (upper and lower case)
2648
2650{
2651 unsigned int iimx[4][4] = {
2652 {0x0, 0xffffff08, 0xafffffff, 0x2ffffffe}, // opt = 0
2653 {0x0, 0x3ff0000, 0x7fffffe, 0x7fffffe}, // opt = 1
2654 {0x0, 0x3ff0000, 0x7e, 0x7e}, // opt = 2
2655 {0x0, 0x3ffc000, 0x7fffffe, 0x7fffffe} // opt = 3
2656 };
2657
2658 const char *cOpt[4] = { "Any", "LetNum", "Hex", "Crypt" };
2659
2660 // Default option 0
2661 if (opt < 0 || opt > 2) {
2662 opt = 0;
2663 if (gDebug > 2)
2664 Info("GetRandString", "unknown option: %d : assume 0", opt);
2665 }
2666 if (gDebug > 2)
2667 Info("GetRandString", "enter ... len: %d %s", len, cOpt[opt]);
2668
2669 // Allocate buffer
2670 char *buf = new char[len + 1];
2671
2672 // Init random machine (if needed)
2674
2675 // randomize
2676 Int_t k = 0;
2677 Int_t i, j, l, m, frnd;
2678 while (k < len) {
2679 frnd = auth_rand();
2680 for (m = 7; m < 32; m += 7) {
2681 i = 0x7F & (frnd >> m);
2682 j = i / 32;
2683 l = i - j * 32;
2684 if ((iimx[opt][j] & (1 << l))) {
2685 buf[k] = i;
2686 k++;
2687 }
2688 if (k == len)
2689 break;
2690 }
2691 }
2692
2693 // null terminated
2694 buf[len] = 0;
2695 if (gDebug > 3)
2696 Info("GetRandString", "got '%s' ", buf);
2697
2698 return buf;
2699}
2700
2701////////////////////////////////////////////////////////////////////////////////
2702/// Encode null terminated str using the session private key indicated by enc
2703/// and sends it over the network
2704/// Returns number of bytes sent, or -1 in case of error.
2705/// enc = 1 for private encoding, enc = 2 for public encoding
2706
2708{
2709 char buftmp[kMAXSECBUF];
2710 char buflen[20];
2711
2712 if (gDebug > 2)
2713 ::Info("TAuthenticate::SecureSend", "local: enter ... (enc: %d)", enc);
2714
2715 Int_t slen = strlen(str) + 1;
2716 Int_t ttmp = 0;
2717 Int_t nsen = -1;
2718
2719 if (key == 0) {
2720 strlcpy(buftmp, str, slen+1);
2721
2722 if (enc == 1)
2723 ttmp = TRSA_fun::RSA_encode()(buftmp, slen, fgRSAPriKey.n,
2724 fgRSAPriKey.e);
2725 else if (enc == 2)
2726 ttmp = TRSA_fun::RSA_encode()(buftmp, slen, fgRSAPubKey.n,
2727 fgRSAPubKey.e);
2728 else
2729 return nsen;
2730 } else if (key == 1) {
2731
2732#ifdef R__SSL
2733 ttmp = strlen(str);
2734 if ((ttmp % 8) > 0) // It should be a multiple of 8!
2735 ttmp = ((ttmp + 8)/8) * 8;
2736 unsigned char iv[8];
2737 memset((void *)&iv[0],0,8);
2738 BF_cbc_encrypt((const unsigned char *)str, (unsigned char *)buftmp,
2739 strlen(str), &fgBFKey, iv, BF_ENCRYPT);
2740#else
2741 if (gDebug > 0)
2742 ::Info("TAuthenticate::SecureSend","not compiled with SSL support:"
2743 " you should not have got here!");
2744#endif
2745 } else {
2746 if (gDebug > 0)
2747 ::Info("TAuthenticate::SecureSend","unknown key type (%d)",key);
2748 return nsen;
2749 }
2750
2751 snprintf(buflen,20,"%d",ttmp);
2752 if (sock->Send(buflen, kROOTD_ENCRYPT) < 0)
2753 return -1;
2754 nsen = sock->SendRaw(buftmp, ttmp);
2755 if (gDebug > 3)
2756 ::Info("TAuthenticate::SecureSend",
2757 "local: sent %d bytes (expected: %d)", nsen,ttmp);
2758
2759 return nsen;
2760}
2761
2762////////////////////////////////////////////////////////////////////////////////
2763/// Receive str from sock and decode it using key indicated by key type
2764/// Return number of received bytes or -1 in case of error.
2765/// dec = 1 for private decoding, dec = 2 for public decoding
2766
2768{
2769
2770 char buftmp[kMAXSECBUF];
2771 char buflen[20];
2772
2773 Int_t nrec = -1;
2774 // We must get a pointer ...
2775 if (!str)
2776 return nrec;
2777
2778 Int_t kind;
2779 if (sock->Recv(buflen, 20, kind) < 0)
2780 return -1;
2781 Int_t len = atoi(buflen);
2782 if (gDebug > 3)
2783 ::Info("TAuthenticate::SecureRecv", "got len '%s' %d (msg kind: %d)",
2784 buflen, len, kind);
2785 if (len == 0) {
2786 return len;
2787 }
2789 return nrec;
2790 }
2791
2792 // Receive buffer
2793 if ((nrec = sock->RecvRaw(buftmp, len)) < 0)
2794 return nrec;
2795 if (key == 0) {
2796 if (dec == 1)
2797 TRSA_fun::RSA_decode()(buftmp, len, fgRSAPriKey.n, fgRSAPriKey.e);
2798 else if (dec == 2)
2799 TRSA_fun::RSA_decode()(buftmp, len, fgRSAPubKey.n, fgRSAPubKey.e);
2800 else
2801 return -1;
2802
2803 // Prepare output
2804 const size_t strSize = strlen(buftmp) + 1;
2805 *str = new char[strSize];
2806 if (*str == nullptr) {
2807 if (gDebug > 0)
2808 ::Info("TAuthenticate::SecureRecv","Memory allocation error size (%ld)", (long) strSize);
2809 return -1;
2810 }
2811 strlcpy(*str, buftmp, strSize);
2812
2813 } else if (key == 1) {
2814#ifdef R__SSL
2815 unsigned char iv[8];
2816 memset((void *)&iv[0],0,8);
2817 *str = new char[nrec + 1];
2818 BF_cbc_encrypt((const unsigned char *)buftmp, (unsigned char *)(*str),
2820 (*str)[nrec] = '\0';
2821#else
2822 if (gDebug > 0)
2823 ::Info("TAuthenticate::SecureRecv","not compiled with SSL support:"
2824 " you should not have got here!");
2825#endif
2826 } else {
2827 if (gDebug > 0)
2828 ::Info("TAuthenticate::SecureRecv","unknown key type (%d)",key);
2829 return -1;
2830 }
2831
2832 nrec= strlen(*str);
2833
2834 return nrec;
2835}
2836
2837////////////////////////////////////////////////////////////////////////////////
2838/// Store RSA public keys from export string rsaPubExport.
2839
2841 R__rsa_NUMBER &rsa_d, char **rsassl)
2842{
2843 if (!rsaPubExport)
2844 return -1;
2845
2846 if (gDebug > 2)
2847 ::Info("TAuthenticate::DecodeRSAPublic",
2848 "enter: string length: %ld bytes", (Long_t)strlen(rsaPubExport));
2849
2850 char str[kMAXPATHLEN] = { 0 };
2852 if (klen > kMAXPATHLEN - 1) {
2853 ::Info("TAuthenticate::DecodeRSAPublic",
2854 "key too long (%d): truncate to %d",klen,kMAXPATHLEN);
2855 klen = kMAXPATHLEN - 1;
2856 }
2857 memcpy(str, rsaPubExport, klen);
2858 str[klen] ='\0';
2859
2860 Int_t keytype = -1;
2861
2862 if (klen > 0) {
2863
2864 // Skip spaces at beginning, if any
2865 int k = 0;
2866 while (str[k] == 32) k++;
2867
2868 if (str[k] == '#') {
2869
2870 keytype = 0;
2871
2872 // The format is #<hex_n>#<hex_d>#
2873 char *pd1 = strstr(str, "#");
2874 char *pd2 = pd1 ? strstr(pd1 + 1, "#") : (char *)0;
2875 char *pd3 = pd2 ? strstr(pd2 + 1, "#") : (char *)0;
2876 if (pd1 && pd2 && pd3) {
2877 // Get <hex_n> ...
2878 int l1 = (int) (pd2 - pd1 - 1);
2879 char *rsa_n_exp = new char[l1 + 1];
2880 strlcpy(rsa_n_exp, pd1 + 1, l1+1);
2881 if (gDebug > 2)
2882 ::Info("TAuthenticate::DecodeRSAPublic",
2883 "got %ld bytes for rsa_n_exp", (Long_t)strlen(rsa_n_exp));
2884 // Now <hex_d>
2885 int l2 = (int) (pd3 - pd2 - 1);
2886 char *rsa_d_exp = new char[l2 + 1];
2887 strlcpy(rsa_d_exp, pd2 + 1, 13);
2888 if (gDebug > 2)
2889 ::Info("TAuthenticate::DecodeRSAPublic",
2890 "got %ld bytes for rsa_d_exp", (Long_t)strlen(rsa_d_exp));
2891
2894
2895 delete[] rsa_n_exp;
2896 delete[] rsa_d_exp;
2897
2898 } else
2899 ::Info("TAuthenticate::DecodeRSAPublic","bad format for input string");
2900#ifdef R__SSL
2901 } else {
2902 // try SSL
2903 keytype = 1;
2904
2905 RSA *rsatmp;
2906
2907 // Bio for exporting the pub key
2908 BIO *bpub = BIO_new(BIO_s_mem());
2909
2910 // Write key from kbuf to BIO
2911 BIO_write(bpub,(void *)str,strlen(str));
2912
2913 // Read pub key from BIO
2914 if (!(rsatmp = PEM_read_bio_RSAPublicKey(bpub, 0, 0, 0))) {
2915 if (gDebug > 0)
2916 ::Info("TAuthenticate::DecodeRSAPublic",
2917 "unable to read pub key from bio");
2918 } else
2919 if (rsassl)
2920 *rsassl = (char *)rsatmp;
2921 else
2922 ::Info("TAuthenticate::DecodeRSAPublic",
2923 "no space allocated for output variable");
2924 BIO_free(bpub);
2925 }
2926#else
2927 } else {
2928 if (rsassl) { } // To avoid compiler complains
2929 if (gDebug > 0)
2930 ::Info("TAuthenticate::DecodeRSAPublic","not compiled with SSL support:"
2931 " you should not have got here!");
2932 }
2933#endif
2934 }
2935
2936 return keytype;
2937}
2938
2939////////////////////////////////////////////////////////////////////////////////
2940/// Store RSA public keys from export string rsaPubExport.
2941/// Returns type of stored key, or -1 is not recognized
2942
2944{
2945 if (gDebug > 2)
2946 ::Info("TAuthenticate::SetRSAPublic",
2947 "enter: string length %ld bytes", (Long_t)strlen(rsaPubExport));
2948
2949 Int_t rsakey = -1;
2950 if (!rsaPubExport)
2951 return rsakey;
2952
2953 if (klen > 0) {
2954
2955 // Skip spaces at beginning, if any
2956 int k0 = 0;
2957 while (rsaPubExport[k0] == 32) k0++;
2958 int k2 = klen - 1;
2959
2960 // Parse rsaPubExport
2961 // Type 0 is in the form
2962 //
2963 // #< gt 10 exa chars >#< gt 10 exa chars >#
2964 //
2965 rsakey = 1;
2966 if (rsaPubExport[k0] == '#' && rsaPubExport[k2] == '#') {
2967 char *p0 = (char *)&rsaPubExport[k0];
2968 char *p2 = (char *)&rsaPubExport[k2];
2969 char *p1 = strchr(p0+1,'#');
2970 if (p1 > p0 && p1 < p2) {
2971 Int_t l01 = (Int_t)(p1-p0)-1;
2972 Int_t l12 = (Int_t)(p2-p1)-1;
2973 if (l01 >= kPRIMELENGTH*2 && l12 >= kPRIMELENGTH*2) {
2974 // Require exadecimal chars in between
2975 char *c = p0+1;
2976 while (c < p1 && ((*c < 58 && *c > 47) || (*c < 91 && *c > 64)))
2977 c++;
2978 if (c == p1) {
2979 c++;
2980 while (c < p2 && ((*c < 58 && *c > 47) || (*c < 91 && *c > 64)))
2981 c++;
2982 if (c == p2)
2983 rsakey = 0;
2984 }
2985 }
2986 }
2987 }
2988 if (gDebug > 3)
2989 ::Info("TAuthenticate::SetRSAPublic"," Key type: %d",rsakey);
2990 if (rsakey == 0) {
2991
2992 // Decode input string
2995
2996 // Save Public key
2997 TRSA_fun::RSA_assign()(&fgRSAPubKey.n, &rsa_n);
2998 TRSA_fun::RSA_assign()(&fgRSAPubKey.e, &rsa_d);
2999
3000 } else {
3001 rsakey = 1;
3002#ifdef R__SSL
3003 // Now set the key locally in BF form
3004 BF_set_key(&fgBFKey, klen, (const unsigned char *)rsaPubExport);
3005#else
3006 if (gDebug > 0)
3007 ::Info("TAuthenticate::SetRSAPublic",
3008 "not compiled with SSL support:"
3009 " you should not have got here!");
3010#endif
3011 }
3012 }
3013
3014 return rsakey;
3015}
3016
3017////////////////////////////////////////////////////////////////////////////////
3018/// Receives server RSA Public key
3019/// Sends local RSA public key encoded
3020
3022{
3023 // Receive server public key
3025 int kind, nr = 0;
3026 if ((nr = socket->Recv(serverPubKey, kMAXSECBUF, kind)) < 0)
3027 return nr;
3028 if (gDebug > 3)
3029 ::Info("TAuthenticate::SendRSAPublicKey",
3030 "received key from server %ld bytes", (Long_t)strlen(serverPubKey));
3031
3032 // Decode it
3034#ifdef R__SSL
3035 char *tmprsa = nullptr;
3037 &tmprsa) != key) {
3038 if (tmprsa)
3039 RSA_free((RSA *)tmprsa);
3040 return -1;
3041 }
3042 RSA *RSASSLServer = (RSA *)tmprsa;
3043#else
3045 return -1;
3046#endif
3047
3048 // Send local public key, encodes
3049 char buftmp[kMAXSECBUF] = {0};
3050 char buflen[20] = {0};
3051 Int_t slen = fgRSAPubExport[key].len;
3052 Int_t ttmp = 0;
3053 if (key == 0) {
3054 strlcpy(buftmp, fgRSAPubExport[key].keys, sizeof(buftmp));
3055 ttmp = TRSA_fun::RSA_encode()(buftmp, slen, rsa_n, rsa_d); // NOLINT: rsa_n, rsa_d are initialized
3056 snprintf(buflen, sizeof(buflen), "%d", ttmp);
3057 } else if (key == 1) {
3058#ifdef R__SSL
3060 Int_t kk = 0;
3061 Int_t ke = 0;
3062 Int_t ns = slen;
3063 while (ns > 0) {
3064 Int_t lc = (ns > lcmax) ? lcmax : ns ;
3065 if ((ttmp = RSA_public_encrypt(lc,
3066 (unsigned char *)&fgRSAPubExport[key].keys[kk],
3067 (unsigned char *)&buftmp[ke],
3069 char errstr[120];
3071 ::Info("TAuthenticate::SendRSAPublicKey","SSL: error: '%s' ",errstr);
3072 }
3073 kk += lc;
3074 ke += ttmp;
3075 ns -= lc;
3076 }
3077 ttmp = ke;
3078 snprintf(buflen, 20, "%d", ttmp);
3079#else
3080 if (gDebug > 0)
3081 ::Info("TAuthenticate::SendRSAPublicKey","not compiled with SSL support:"
3082 " you should not have got here!");
3083 return -1;
3084#endif
3085 } else {
3086 if (gDebug > 0)
3087 ::Info("TAuthenticate::SendRSAPublicKey","unknown key type (%d)",key);
3088#ifdef R__SSL
3089 if (RSASSLServer)
3091#endif
3092 return -1;
3093 }
3094
3095 // Send length first
3096 if ((nr = socket->Send(buflen, kROOTD_ENCRYPT)) < 0)
3097 return nr;
3098 // Send Key. second ...
3099 Int_t nsen = socket->SendRaw(buftmp, ttmp);
3100 if (gDebug > 3)
3101 ::Info("TAuthenticate::SendRSAPublicKey",
3102 "local: sent %d bytes (expected: %d)", nsen,ttmp);
3103#ifdef R__SSL
3104 if (RSASSLServer)
3106#endif
3107 return nsen;
3108}
3109
3110////////////////////////////////////////////////////////////////////////////////
3111/// Read authentication directives from $ROOTAUTHRC, $HOME/.rootauthrc or
3112/// `<Root_etc_dir>/system.rootauthrc` and create related THostAuth objects.
3113/// Files are read only if they changed since last reading
3114
3116{
3117 // rootauthrc family
3119 if (gSystem->Getenv("ROOTAUTHRC") != 0) {
3120 tRootAuthrc = gSystem->Getenv("ROOTAUTHRC");
3121 } else {
3122 if (fgReadHomeAuthrc) {
3123 tRootAuthrc = ".rootauthrc";
3125 }
3126 }
3127 if (!tRootAuthrc.IsNull() && gDebug > 2)
3128 ::Info("TAuthenticate::ReadRootAuthrc", "Checking file: %s", tRootAuthrc.Data());
3130 if (!tRootAuthrc.IsNull() && gDebug > 1)
3131 ::Info("TAuthenticate::ReadRootAuthrc",
3132 "file %s cannot be read (errno: %d)", tRootAuthrc.Data(), errno);
3133 tRootAuthrc = "system.rootauthrc";
3135 if (gDebug > 2)
3136 ::Info("TAuthenticate::ReadRootAuthrc", "Checking system file: %s", tRootAuthrc.Data());
3138 if (gDebug > 1)
3139 ::Info("TAuthenticate::ReadRootAuthrc",
3140 "file %s cannot be read (errno: %d)", tRootAuthrc.Data(), errno);
3141 return 0;
3142 }
3143 }
3144
3145 // Check if file has changed since last read
3146 if (tRootAuthrc == fgRootAuthrc) {
3147 struct stat si;
3148 stat(tRootAuthrc, &si);
3149 if ((UInt_t)si.st_mtime < fgLastAuthrc.Convert()) {
3150 if (gDebug > 1)
3151 ::Info("TAuthenticate::ReadRootAuthrc",
3152 "file %s already read", tRootAuthrc.Data());
3153 return 0;
3154 }
3155 }
3156
3157 // Save filename in static variable
3158 fgRootAuthrc = tRootAuthrc;
3159 fgLastAuthrc = TDatime();
3160
3161 // THostAuth lists
3163
3164 // Expand File into temporary file name and open it
3165 int expand = 1;
3166 TString filetmp = "rootauthrc";
3168 if (gDebug > 2)
3169 ::Info("TAuthenticate::ReadRootAuthrc", "got tmp file: %s open at 0x%zx",
3170 filetmp.Data(), (size_t)ftmp);
3171 if (ftmp == 0)
3172 expand = 0; // Problems opening temporary file: ignore 'include's ...
3173
3174 FILE *fd = 0;
3175 // If the temporary file is open, copy everything to the new file ...
3176 if (expand == 1) {
3178 fd = ftmp;
3179 rewind(fd);
3180 } else {
3181 // Open file
3182 fd = fopen(tRootAuthrc, "r");
3183 if (fd == 0) {
3184 if (gDebug > 2)
3185 ::Info("TAuthenticate::ReadRootAuthrc",
3186 "file %s cannot be open (errno: %d)", tRootAuthrc.Data(), errno);
3187 return 0;
3188 }
3189 }
3190
3191 // Now scan file for meaningful directives
3193 char line[kMAXPATHLEN];
3194 while (fgets(line, sizeof(line), fd) != 0) {
3195
3196 // Skip comment lines
3197 if (line[0] == '#')
3198 continue;
3199
3200 // Get rid of end of line '\n', if there ...
3201 if (line[strlen(line) - 1] == '\n')
3202 line[strlen(line) - 1] = '\0';
3203
3204 // Skip empty lines
3205 if (!line[0])
3206 continue;
3207
3208 // Now scan
3209 const size_t tmpSize = strlen(line) + 1;
3210 char *tmp = new char[tmpSize];
3211 if (!tmp) {
3212 ::Error("TAuthenticate::ReadRootAuthrc",
3213 "could not allocate temporary buffer");
3214 fclose(fd);
3215 return 0;
3216 }
3218 char *nxt = strtok(tmp," ");
3219
3220
3222 TString host = hostsrv;
3223 TString server = "";
3224 if (hostsrv.Contains(":")) {
3225 server = hostsrv;
3226 host.Remove(host.Index(":"));
3227 server.Remove(0,server.Index(":")+1);
3228 }
3229 Int_t srvtyp = -1;
3230 if (server.Length()) {
3231 if (server == "0" || server.BeginsWith("sock"))
3233 else if (server == "1" || server.BeginsWith("root"))
3235 }
3236
3237 // Line with host info directives
3238 TString user = "*";
3239
3240 nxt = strtok(0," ");
3241 if (!strncmp(nxt,"user",4)) {
3242 nxt = strtok(0," ");
3243 if (strncmp(nxt,"list",4) && strncmp(nxt,"method",6)) {
3244 user = TString(nxt);
3245 nxt = strtok(0," ");
3246 }
3247 }
3248
3249 // Get related THostAuth, if exists in the tmp list,
3250 TIter next(&tmpAuthInfo);
3251 THostAuth *ha;
3252 while ((ha = (THostAuth *)next())) {
3253 if (host == ha->GetHost() && user == ha->GetUser() &&
3254 srvtyp == ha->GetServer())
3255 break;
3256 }
3257 if (!ha) {
3258 // Create a new one
3259 ha = new THostAuth(host,srvtyp,user);
3260 tmpAuthInfo.Add(ha);
3261 }
3262
3263 if (!strncmp(nxt,"list",4)) {
3264 // list of methods for {host,usr}
3265 Int_t nm = 0, me[kMAXSEC] = {0};
3266 char *mth = strtok(0," ");
3267 while (mth) {
3268 Int_t met = -1;
3269 if (strlen(mth) > 1) {
3270 // Method passed as string: translate it to number
3271 met = GetAuthMethodIdx(mth);
3272 if (met == -1 && gDebug > 2)
3273 ::Info("TAuthenticate::ReadRootAuthrc",
3274 "unrecognized method (%s): ", mth);
3275 } else {
3276 met = atoi(mth);
3277 }
3278 if (met > -1 && met < kMAXSEC)
3279 me[nm++] = met;
3280 mth = strtok(0," ");
3281 }
3282 if (nm)
3283 ha->ReOrder(nm,me);
3284
3285 } else if (!strncmp(nxt,"method",6)) {
3286
3287 // details for {host,usr,method}
3288 char *mth = strtok(0," ");
3289 Int_t met = -1;
3290 if (strlen(mth) > 1) {
3291 // Method passed as string: translate it to number
3292 met = GetAuthMethodIdx(mth);
3293 if (met == -1 && gDebug > 2)
3294 ::Info("TAuthenticate::ReadRootAuthrc",
3295 "unrecognized method (%s): ", mth);
3296 } else {
3297 met = atoi(mth);
3298 }
3299 if (met > -1 && met < kMAXSEC) {
3300 const char *det = 0;
3301 nxt = strtok(0," ");
3302 if (nxt) {
3303 det = (const char *)strstr(line,nxt);
3304 }
3305 if (ha->HasMethod(met))
3306 ha->SetDetails(met,det);
3307 else
3308 ha->AddMethod(met,det);
3309 }
3310 }
3311 if (tmp) delete [] tmp;
3312 }
3313 // Close file and remove it if temporary
3314 fclose(fd);
3315 if (expand == 1)
3317
3318 // Update authinfo with new info found
3320
3321 // Print those left, if requested ...
3322 if (gDebug > 2)
3324
3325 return authinfo->GetSize();
3326}
3327
3328////////////////////////////////////////////////////////////////////////////////
3329/// Standard version of CheckSecCtx to be passed to TAuthenticate::AuthExists
3330/// Check if User is matches the one in Ctx
3331/// Returns: 1 if ok, 0 if not
3332/// Deactivates Ctx is not valid
3333
3335{
3336 Int_t rc = 0;
3337
3338 if (ctx->IsActive()) {
3339 if (!strcmp(user,ctx->GetUser()) &&
3340 strncmp("AFS", ctx->GetID(), 3))
3341 rc = 1;
3342 }
3343 return rc;
3344}
3345
3346////////////////////////////////////////////////////////////////////////////////
3347/// Tool for updating fgAuthInfo
3348/// 'nin' contains list of last input information through (re)reading
3349/// of a rootauthrc-alike file. 'nin' info has priority.
3350/// 'std' is cleaned from inactive members.
3351/// 'nin' members used to update existing members in 'std' are
3352/// removed from 'nin', do that they do not leak
3353
3355{
3356 // Remove inactive from the 'std'
3357 TIter nxstd(std);
3358 THostAuth *ha;
3359 while ((ha = (THostAuth *) nxstd())) {
3360 if (!ha->IsActive()) {
3361 std->Remove(ha);
3362 SafeDelete(ha);
3363 }
3364 }
3365
3366 // Merge 'nin' info in 'std'
3367 TIter nxnew(nin);
3369 while ((hanew = (THostAuth *)nxnew())) {
3370 if (hanew->NumMethods()) {
3372 hostsrv.Form("%s:%d",hanew->GetHost(),hanew->GetServer());
3373 THostAuth *hastd =
3375 if (hastd) {
3376 // Update with new info
3377 hastd->Update(hanew);
3378 // Flag for removal
3379 hanew->DeActivate();
3380 } else {
3381 // Add new ThostAuth to std
3382 std->Add(hanew);
3383 }
3384 } else
3385 // Flag for removal empty objects
3386 hanew->DeActivate();
3387 }
3388
3389 // Cleanup memory before quitting
3390 nxnew.Reset();
3391 while ((hanew = (THostAuth *)nxnew())) {
3392 if (!hanew->IsActive()) {
3393 nin->Remove(hanew);
3395 }
3396 }
3397
3398}
3399
3400////////////////////////////////////////////////////////////////////////////////
3401/// Tool for removing SecContext ctx from THostAuth listed in
3402/// fgAuthInfo
3403
3405{
3407
3408 // authinfo first
3409 TIter nxai(GetAuthInfo());
3410 while ((ha = (THostAuth *)nxai())) {
3411 TIter next(ha->Established());
3412 TRootSecContext *lctx = 0;
3413 while ((lctx = (TRootSecContext *) next())) {
3414 if (lctx == ctx) {
3415 ha->Established()->Remove(ctx);
3416 break;
3417 }
3418 }
3419 }
3420}
3421
3422////////////////////////////////////////////////////////////////////////////////
3423/// Static method returning supported client protocol.
3424
3429
@ kROOTD_RSAKEY
@ kROOTD_ENCRYPT
@ kROOTD_PASS
@ kMESS_STRING
@ kROOTD_USER
@ kROOTD_BYE
@ kROOTD_NEGOTIA
@ kROOTD_AUTH
@ kROOTD_ERR
R__EXTERN const char * gRootdErrStr[]
Definition NetErrors.h:72
@ kErrNotAllowed
Definition NetErrors.h:49
@ kErrConnectionRefused
Definition NetErrors.h:50
@ kErrError
Definition NetErrors.h:69
#define SafeDelete(p)
Definition RConfig.hxx:531
#define c(i)
Definition RSha256.hxx:101
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:131
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
@ kMAXPATHLEN
Definition Rtypes.h:61
TVirtualMutex *& gAuthenticateMutex
static Int_t StdCheckSecCtx(const char *, ROOT::Deprecated::TRootSecContext *)
Standard version of CheckSecCtx to be passed to TAuthenticate::AuthExists Check if User is matches th...
static int auth_rand()
rand() implementation using /udev/random or /dev/random, if available
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
char name[80]
Definition TGX11.cxx:148
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:783
#define gROOT
Definition TROOT.h:426
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2495
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2509
char * StrDup(const char *str)
Duplicate the string str.
Definition TString.cxx:2563
@ kReadPermission
Definition TSystem.h:55
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:126
Bool_t R_ISDIR(Int_t mode)
Definition TSystem.h:123
R__EXTERN TSystem * gSystem
Definition TSystem.h:582
@ kS_IWUSR
Definition TSystem.h:111
@ kS_IRUSR
Definition TSystem.h:110
#define R__LOCKGUARD2(mutex)
const char * proto
Definition civetweb.c:18822
#define snprintf
Definition civetweb.c:1579
static const char * GetDefaultUser()
Static method returning the default user information.
static const char * GetGlobalUser()
Static method returning the global user.
static GlobusAuth_t GetGlobusAuthHook()
Static method returning the globus authorization hook (no longer supported)
static void RemoveSecContext(TRootSecContext *ctx)
Tool for removing SecContext ctx from THostAuth listed in fgAuthInfo.
void CatchTimeOut()
Called in connection with a timer timeout.
static char * GetDefaultDetails(Int_t method, Int_t opt, const char *user)
Determine default authentication details for method 'sec' and user 'usr'.
static void MergeHostAuthList(TList *Std, TList *New, Option_t *Opt="")
Tool for updating fgAuthInfo 'nin' contains list of last input information through (re)reading of a r...
Int_t AuthExists(TString User, Int_t method, const char *Options, Int_t *Message, Int_t *Rflag, CheckSecCtx_t funcheck)
Check if we have a valid established sec context in memory Retrieves relevant info and negotiates wit...
static TDatime GetGlobalExpDate()
Static method returning default expiring date for new validity contexts.
static Int_t ReadRootAuthrc()
Read authentication directives from $ROOTAUTHRC, $HOME/.rootauthrc or <Root_etc_dir>/system....
char * GetRandString(Int_t Opt, Int_t Len)
Allocates and fills a 0 terminated buffer of length len+1 with len random characters.
static void SetGlobalPwHash(Bool_t pwhash)
Set global passwd hash flag to be used for authentication to rootd.
static R__rsa_KEY_export * fgRSAPubExport
static void SetKrb5AuthHook(Krb5Auth_t func)
Set kerberos5 authorization function.
Int_t SshAuth(TString &user)
SSH client authentication code (no longer supported)
static void SetGlobalPasswd(const char *passwd)
Set global passwd to be used for authentication to rootd.
static TString fgAuthMeth[kMAXSEC]
static void SetDefaultUser(const char *defaultuser)
Set default user name.
static void RemoveHostAuth(THostAuth *ha, Option_t *opt="")
Remove THostAuth instance from the list.
static void Show(Option_t *opt="S")
Print info about the authentication sector.
static Int_t GetRSAInit()
Static method returning the RSA initialization flag.
static Int_t DecodeRSAPublic(const char *rsapubexport, R__rsa_NUMBER &n, R__rsa_NUMBER &d, char **rsassl=nullptr)
Store RSA public keys from export string rsaPubExport.
static void SetDefaultRSAKeyType(Int_t key)
Static method setting the default type of RSA key.
static Int_t GetAuthMethodIdx(const char *meth)
Static method returning the method index (which can be used to find the method in GetAuthMethod()).
static void SetGlobalExpDate(TDatime expdate)
Set default expiring date for new validity contexts.
static TPluginHandler * fgPasswdDialog
static Int_t SetRSAPublic(const char *rsapubexport, Int_t klen)
Store RSA public keys from export string rsaPubExport.
static TList * GetAuthInfo()
Static method returning the list with authentication details.
void SetEnvironment()
Set default authentication environment.
static void SetTimeOut(Int_t to)
Set timeout (active if > 0)
static Bool_t GetAuthReUse()
Static method returning the authentication reuse settings.
static void FileExpand(const char *fin, FILE *ftmp)
Expands include directives found in fexp files The expanded, temporary file, is pointed to by 'ftmp' ...
static SecureAuth_t fgSecAuthHook
static const char * GetKrb5Principal()
Static method returning the principal to be used to init Krb5 tickets.
static Int_t SecureSend(TSocket *Socket, Int_t enc, Int_t KeyType, const char *In)
Encode null terminated str using the session private key indicated by enc and sends it over the netwo...
static Bool_t GetPromptUser()
Static method returning the prompt user settings.
static void SetGlobalSRPPwd(Bool_t srppwd)
Set global SRP passwd flag to be used for authentication to rootd.
static void SetSecureAuthHook(SecureAuth_t func)
Set secure authorization function.
Bool_t Authenticate()
Authenticate to remote rootd server.
Int_t RfioAuth(TString &user)
RFIO authentication (no longer supported)
static void SetAuthReUse(Bool_t authreuse)
Set global AuthReUse flag.
static Int_t GetClientProtocol()
Static method returning supported client protocol.
static char * PromptUser(const char *remote)
Static method to prompt for the user name to be used for authentication to rootd.
static Bool_t GetGlobalPwHash()
Static method returning the global password hash flag.
static void SetGlobalUser(const char *user)
Set global user name to be used for authentication to rootd.
static void SetPromptUser(Bool_t promptuser)
Set global PromptUser flag.
static char * PromptPasswd(const char *prompt="Password: ")
Static method to prompt for the user's passwd to be used for authentication to rootd.
TAuthenticate(TSocket *sock, const char *remote, const char *proto, const char *user="")
Create authentication object.
THostAuth * GetHostAuth() const
Int_t GenRSAKeys()
Generate a valid pair of private/public RSA keys to protect for authentication token exchange.
static Bool_t CheckHost(const char *Host, const char *host)
Check if 'host' matches 'href': this means either equal or "containing" it, even with wild cards * in...
static void SetRSAInit(Int_t init=1)
Static method setting RSA initialization flag.
static void InitRandom()
Initialize random machine using seed from /dev/urandom (or current time if /dev/urandom not available...
static void SetGlobusAuthHook(GlobusAuth_t func)
Set Globus authorization function.
static const char * GetAuthMethod(Int_t idx)
Static method returning the method corresponding to idx.
static Bool_t GetGlobalSRPPwd()
Static method returning the global SRP password flag.
Bool_t GetUserPasswd(TString &user, TString &passwd, Bool_t &pwhash, Bool_t srppwd)
Try to get user name and passwd from several sources.
const char * GetSshUser(TString user) const
Method returning the user to be used for the ssh login (no longer supported)
static Int_t SecureRecv(TSocket *Socket, Int_t dec, Int_t KeyType, char **Out)
Receive str from sock and decode it using key indicated by key type Return number of received bytes o...
static Int_t SendRSAPublicKey(TSocket *Socket, Int_t key=0)
Receives server RSA Public key Sends local RSA public key encoded.
Int_t ClearAuth(TString &user, TString &passwd, Bool_t &pwhash)
UsrPwd client authentication code.
static void AuthError(const char *where, Int_t error)
Print error string depending on error code.
static THostAuth * HasHostAuth(const char *host, const char *user, Option_t *opt="R")
Checks if a THostAuth with exact match for {host,user} exists in the fgAuthInfo list Returns pointer ...
static const char * GetRSAPubExport(Int_t key=0)
Static method returning the RSA public keys.
Bool_t CheckNetrc(TString &user, TString &passwd)
Try to get user name and passwd from the ~/.rootnetrc or ~/.netrc files.
void SetHost(const char *host)
Definition THostAuth.h:97
void AddFirst(Int_t level, const char *details=nullptr)
Add new method in first position If already in the list, set as first method 'level' with authenticat...
TList * Established() const
Definition THostAuth.h:101
void SetFirst(Int_t level)
Set 'method' to be the first used (if in the list ...).
Bool_t HasMethod(Int_t level, Int_t *pos=nullptr)
Return kTRUE if method 'level' is in the list.
void SetUser(const char *user)
Definition THostAuth.h:99
void SetServer(Int_t server)
Definition THostAuth.h:98
const char * GetHost() const
Definition THostAuth.h:93
void Print(Option_t *option="F") const override
If opt is "F" (default) print object content.
const char * GetUser() const
Definition TSecContext.h:82
Bool_t IsActive() const
Check remote OffSet and expiring Date.
const char * GetID() const
Definition TSecContext.h:76
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition TDatime.h:37
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:503
This class represents an Internet Protocol (IP) address.
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:952
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1069
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3390
static RSA_encode_t RSA_encode()
Definition rsafun.cxx:58
static RSA_genprim_t RSA_genprim()
Definition rsafun.cxx:56
static RSA_assign_t RSA_assign()
Definition rsafun.cxx:64
static RSA_cmp_t RSA_cmp()
Definition rsafun.cxx:65
static RSA_decode_t RSA_decode()
Definition rsafun.cxx:59
static RSA_genrsa_t RSA_genrsa()
Definition rsafun.cxx:57
static RSA_num_sput_t RSA_num_sput()
Definition rsafun.cxx:60
static RSA_num_sget_t RSA_num_sget()
Definition rsafun.cxx:62
Regular expression class.
Definition TRegexp.h:31
This class implements client sockets.
Definition TSocket.h:54
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition TSocket.cxx:827
static Int_t GetClientProtocol()
Static method returning supported client protocol.
Definition TSocket.cxx:1467
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition TSocket.cxx:922
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition TSocket.cxx:629
@ kSOCKD
Definition TSocket.h:64
@ kROOTD
Definition TSocket.h:64
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition TSocket.cxx:531
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition TString.h:703
const char * Data() const
Definition TString.h:384
@ kIgnoreCase
Definition TString.h:285
TString & Remove(Ssiz_t pos)
Definition TString.h:694
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2362
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:660
virtual FILE * TempFileName(TString &base, const char *dir=nullptr, const char *suffix=nullptr)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition TSystem.cxx:1510
virtual int GetPid()
Get process id.
Definition TSystem.cxx:716
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1676
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1868
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition TSystem.cxx:1409
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1092
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition TSystem.cxx:1307
virtual void DispatchOneEvent(Bool_t pendingOnly=kFALSE)
Dispatch a single event.
Definition TSystem.cxx:427
virtual const char * HostName()
Return the system's host name.
Definition TSystem.cxx:301
virtual Int_t GetEffectiveUid()
Returns the effective user id.
Definition TSystem.cxx:1583
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition TSystem.cxx:2302
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:897
virtual int Unlink(const char *name)
Unlink, i.e.
Definition TSystem.cxx:1392
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition TSystem.cxx:1612
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2031
Handles synchronous and a-synchronous timer events.
Definition TTimer.h:51
This class implements a mutex interface.
TPaveText * pt
TLine * line
TSeqCollection * GetListOfSecContexts(const TROOT &)
Definition TROOT.cxx:175
const Int_t kMAXRSATRIES
Definition AuthConst.h:34
const Int_t kMAXSECBUF
Definition AuthConst.h:29
const Int_t kPRIMEEXP
Definition AuthConst.h:36
const Int_t kPRIMELENGTH
Definition AuthConst.h:35
Int_t(* GlobusAuth_t)(ROOT::Deprecated::TAuthenticate *auth, TString &user, TString &det)
const Int_t kAUTH_REUSE_MSK
Definition AuthConst.h:30
const Int_t kAUTH_CRYPT_MSK
Definition AuthConst.h:31
const Int_t kMAXSEC
Definition AuthConst.h:28
R__rsa_KEY_export R__fgRSAPubExport[2]
R__EXTERN TVirtualMutex * gAuthenticateMutex
const Int_t kAUTH_SSALT_MSK
Definition AuthConst.h:32
const Int_t kAUTH_RSATY_MSK
Definition AuthConst.h:33
void inv(rsa_NUMBER *, rsa_NUMBER *, rsa_NUMBER *)
Definition rsaaux.cxx:949
#define rsa_STRLEN
Definition rsadef.h:87
Int_t fMode
Definition TSystem.h:135
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
auto * t1
Definition textangle.C:20