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