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