XRootD
Loading...
Searching...
No Matches
XrdSecProtocolztn.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d S e c P r o t o c o l z t n . c c */
4/* */
5/* (c) 2020 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* All Rights Reserved */
7/* Produced by Andrew Hanushevsky for Stanford University under contract */
8/* DE-AC02-76-SFO0515 with the Department of Energy */
9/* */
10/* This file is part of the XRootD software suite. */
11/* */
12/* XRootD is free software: you can redistribute it and/or modify it under */
13/* the terms of the GNU Lesser General Public License as published by the */
14/* Free Software Foundation, either version 3 of the License, or (at your */
15/* option) any later version. */
16/* */
17/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20/* License for more details. */
21/* */
22/* You should have received a copy of the GNU Lesser General Public License */
23/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25/* */
26/* The copyright holder's institutional names and contributor's names may not */
27/* be used to endorse or promote products derived from this software without */
28/* specific prior written permission of the institution or contributor. */
29/******************************************************************************/
30
31#define __STDC_FORMAT_MACROS 1
32
33#include <cctype>
34#include <cerrno>
35#include <fcntl.h>
36#include <cinttypes>
37#include <iostream>
38#include <cstdint>
39#include <cstdio>
40#include <cstdlib>
41#include <cstring>
42#include <ctime>
43#include <vector>
44
45#ifndef __FreeBSD__
46#include <alloca.h>
47#endif
48
49#include <arpa/inet.h>
50#include <sys/stat.h>
51#include <sys/types.h>
52#include <sys/uio.h>
53#include <strings.h>
54#include <unistd.h>
55
56#include "XrdVersion.hh"
57
59#include "XrdOuc/XrdOucEnv.hh"
65#include "XrdSys/XrdSysE2T.hh"
68
69#ifndef EAUTH
70#define EAUTH EBADE
71#endif
72/******************************************************************************/
73/* V e r s i o n I n f o r m a t i o n */
74/******************************************************************************/
75
77
78/******************************************************************************/
79/* L o c a l F u n c t i o n s */
80/******************************************************************************/
81/******************************************************************************/
82/* F a t a l */
83/******************************************************************************/
84
85namespace
86{
87XrdSecCredentials *Fatal(XrdOucErrInfo *erp, const char *eMsg, int rc,
88 bool hdr=true)
89{
90 if (!erp) std::cerr <<"Secztn: " <<eMsg <<"\n" <<std::flush;
91 else {const char *eVec[2] = {(hdr ? "Secztn: " : ""), eMsg};
92 erp->setErrInfo(rc, eVec, 2);
93 }
94 return 0;
95}
96
97/******************************************************************************/
98/* m o n o t o n i c _ t i m e */
99/******************************************************************************/
100
101inline uint64_t monotonic_time() {
102 struct timespec tp;
103#ifdef CLOCK_MONOTONIC_COARSE
104 clock_gettime(CLOCK_MONOTONIC_COARSE, &tp);
105#else
106 clock_gettime(CLOCK_MONOTONIC, &tp);
107#endif
108 return tp.tv_sec + (tp.tv_nsec >= 500000000);
109}
110
111/******************************************************************************/
112/* G l o b a l S t a t i c D a t a */
113/******************************************************************************/
114
115int expiry = 1;
116bool tokenlib = true;
117}
118
119/******************************************************************************/
120/* g e t L i n k a g e */
121/******************************************************************************/
122
123namespace
124{
125 XrdSciTokensHelper **sth_Linkage = 0;
126 char *sth_piName = 0;
127
128bool getLinkage(XrdOucErrInfo *erp, const char *piName)
129{
130 char eMsgBuff[2048];
131 XrdVersionInfo *myVer = &XrdVERSIONINFOVAR(XrdSecProtocolztnObject);
132 XrdOucPinLoader myLib(eMsgBuff, sizeof(eMsgBuff), myVer,
133 "ztn.tokenlib", piName);
134
135// Get the address of the pointer to the helper we need
136//
137 sth_Linkage = (XrdSciTokensHelper **)(myLib.Resolve("SciTokensHelper"));
138
139// If we succeeded, record the name of the plugin and return success
140//
141 if (sth_Linkage)
142 {sth_piName = strdup(piName);
143 return true;
144 }
145
146// We failed to find this for one reason or another
147//
148 erp->setErrInfo(ESRCH, eMsgBuff);
149 return false;
150 }
151}
152
153/******************************************************************************/
154/* L o c a l D e f i n i t i o n s */
155/******************************************************************************/
156
157namespace
158{
159int MaxTokSize = 4096;
160
161// Option flags
162//
163static const uint64_t srvVNum = 0x00000000000000ffULL;
164static const uint64_t useFirst = 0x0000000000000100ULL;
165static const uint64_t useLast = 0x0000000000000200ULL;
166static const uint64_t srvRTOK = 0x0000000000000800ULL;
167}
168
169/******************************************************************************/
170/* E x t e r n a l L i n k a g e s */
171/******************************************************************************/
172
173namespace XrdSecztn
174{
175extern bool isJWT(const char *);
176}
177
178/******************************************************************************/
179/* X r d S e c P r o t o c o l z t n C l a s s */
180/******************************************************************************/
181
183{
184public:
185
187 XrdSecParameters **parms,
188 XrdOucErrInfo *einfo=0);
189
190 void Delete() {delete this;}
191
193 XrdOucErrInfo *einfo=0);
194
195 bool needTLS() {return true;}
196
197// Client-side constructor
198//
199 XrdSecProtocolztn(const char *parms, XrdOucErrInfo *erp, bool &aOK);
200
201
202// Server-side constructor
203//
204 XrdSecProtocolztn(const char *hname, XrdNetAddrInfo &endPoint,
205 XrdSciTokensHelper *sthp)
206 : XrdSecProtocol("ztn"), sthP(sthp), tokName(""),
207 maxTSize(MaxTokSize), cont(false),
208 rtGet(false), verJWT(false)
209 {Entity.host = strdup(hname);
210 Entity.name = strdup("anon");
211 Entity.addrInfo = &endPoint;
212 }
213
215 if (Entity.name) free(Entity.name);
216 if (Entity.creds)free(Entity.creds);
217 } // via Delete()
218
219static const int ztnVersion = 0;
220
221private:
222
223
224struct TokenHdr
225 {char id[4];
226 char ver;
227 char opr;
228 char rsvd[2]; // Reserved bytes (note struct is 8 bytes long)
229
230 static const char SndAI = 'S';
231 static const char IsTkn = 'T';
232
233 void Fill(char opc) {strcpy(id, "ztn"); ver = ztnVersion;
234 opr = opc; rsvd[0] = rsvd[1] = 0;
235 }
236 };
237
238struct TokenResp
239 {TokenHdr hdr;
240 uint16_t len;
241 char tkn[1]; // Sized to actual token length
242 };
243
244XrdSecCredentials *findToken(XrdOucErrInfo *erp,
245 std::vector<XrdOucString> &Vec, bool &isbad);
246XrdSecCredentials *getToken(XrdOucErrInfo *erp, XrdSecParameters *parms);
247XrdSecCredentials *readFail(XrdOucErrInfo *erp, const char *path, int rc);
248XrdSecCredentials *readToken(XrdOucErrInfo *erp, const char *path, bool &isbad);
249XrdSecCredentials *retToken(XrdOucErrInfo *erp, const char *tkn, int tsz);
250int SendAI(XrdOucErrInfo *erp, XrdSecParameters **parms);
251const char *Strip(const char *bTok, int &sz);
252
254const char *tokName;
255uint64_t ztnInfo;
256int maxTSize;
257bool cont;
258bool rtGet;
259bool verJWT;
260};
261
262/******************************************************************************/
263/* C l i e n t O r i e n t e d F u n c t i o n s */
264/******************************************************************************/
265/******************************************************************************/
266/* C o n s t r u c t o r */
267/******************************************************************************/
268
270 bool &aOK)
271 : XrdSecProtocol("ztn"), sthP(0),
272 tokName(""), ztnInfo(0), maxTSize(0),
273 cont(false), rtGet(false), verJWT(false)
274{
275 char *endP;
276
277// Assume we will fail
278//
279 aOK = false;
280
281// If there are no parameters then fail as the server must supply them
282//
283 if (!parms || !(*parms))
284 {Fatal(erp, "Client parameters not specified.", EINVAL);
285 return;
286 }
287
288// Server supplied parms: <opts+ver>:<maxtsz>:
289
290// The first parameter is the options and version number.
291//
292 ztnInfo = strtoll(parms, &endP, 10);
293 if (*endP != ':')
294 {Fatal(erp, "Malformed client parameters.", EINVAL);
295 return;
296 }
297 parms = endP+1;
298
299// The second parameter is the maximum token size
300//
301 maxTSize = strtol(parms, &endP, 10);
302 if (maxTSize <= 0 || *endP != ':')
303 {Fatal(erp, "Invalid or missing maxtsz parameter.", EINVAL);
304 return;
305 }
306 endP++;
307
308// All done here
309//
310 aOK = true;
311}
312
313/******************************************************************************/
314/* Private: f i n d T o k e n */
315/******************************************************************************/
316
317XrdSecCredentials *XrdSecProtocolztn::findToken(XrdOucErrInfo *erp,
318 std::vector<XrdOucString> &Vec,
319 bool &isbad)
320{
321 XrdSecCredentials *resp;
322 const char *aTok, *bTok;
323 int sz;
324
325// Look through all of the possible envars
326//
327 for (int i = 0; i < (int)Vec.size(); i++)
328 {tokName = Vec[i].c_str();
329
330 if (Vec[i].beginswith('/') == 1)
331 {char tokPath[MAXPATHLEN+8];
332 snprintf(tokPath, sizeof(tokPath), tokName, int(geteuid()));
333 resp = readToken(erp, tokPath, isbad);
334 if (resp || isbad) return resp;
335 continue;
336 }
337
338 if (!(aTok = getenv(Vec[i].c_str())) || !*(aTok)) continue;
339
340 if (Vec[i].endswith("_DIR"))
341 {char tokPath[MAXPATHLEN+8];
342 snprintf(tokPath,sizeof(tokPath),"%s/bt_u%d",aTok,int(geteuid()));
343 resp = readToken(erp, tokPath, isbad);
344 if (resp || isbad) return resp;
345 continue;
346 }
347
348 if (Vec[i].endswith("_FILE"))
349 {if ((resp = readToken(erp, aTok, isbad)) || isbad) return resp;
350 continue;
351 }
352
353 if ((bTok = Strip(aTok, sz))) return retToken(erp, bTok, sz);
354 }
355
356// We support passing the credential cache path via Url parameter
357//
358 char *ccn = (erp && erp->getEnv()) ? erp->getEnv()->Get("xrd.ztn") : 0;
359 if (ccn)
360 {
361 resp = readToken(erp, ccn, isbad);
362 if (resp || isbad) return resp;
363 }
364
365// Look through all of the possible envars
366// Nothing found
367//
368 isbad = false;
369 return 0;
370}
371
372/******************************************************************************/
373/* g e t C r e d e n t i a l s */
374/******************************************************************************/
375
377 XrdOucErrInfo *error)
378{
379 static const char *dfltLoc[] = {"BEARER_TOKEN", "BEARER_TOKEN_FILE",
380 "XDG_RUNTIME_DIR", "/tmp/bt_u%d"};
381 static const char **dfltLocEnd = dfltLoc + sizeof(dfltLoc)/sizeof(char*);
382 static std::vector<XrdOucString> dfltVec(dfltLoc, dfltLocEnd);
383
384 XrdSecCredentials *resp;
385 bool isbad;
386
387// If this is a continuation, then handle as such
388//
389 if (cont) return getToken(error, parms);
390
391// Handle the default search
392//
393 resp = findToken(error, dfltVec, isbad);
394 if (resp || isbad) return resp;
395
396// We do not have a envar value then ask the server for a list of
397// token issuers so we can get one, if allowed. Otherwise, it's an error.
398//
399 if (rtGet)
400 {TokenHdr *tHdr = (TokenHdr *)malloc(sizeof(TokenHdr));
401 tHdr->Fill(TokenHdr::SndAI);
402 cont = true;
403 return new XrdSecCredentials((char *)tHdr, sizeof(TokenHdr));
404 }
405 Fatal(error, "No token found; runtime fetch disallowed.", ENOPROTOOPT);
406 return 0;
407}
408
409/******************************************************************************/
410/* Private: g e t T o k e n */
411/******************************************************************************/
412
413XrdSecCredentials *XrdSecProtocolztn::getToken(XrdOucErrInfo *erp,
414 XrdSecParameters *parms)
415{
416// We currently do not support dynamic token creation
417//
418 return Fatal(erp, "Realtime token creation not supported.", ENOTSUP);
419}
420
421/******************************************************************************/
422/* Private: r e a d F a i l */
423/******************************************************************************/
424
425XrdSecCredentials *XrdSecProtocolztn::readFail(XrdOucErrInfo *erp,
426 const char *path, int rc)
427{
428 const char *mVec[7];
429 int k = 6;
430
431 mVec[0] = "Secztn: Unable to find token via ";
432 mVec[1] = tokName;
433 mVec[2] = "=";
434 mVec[3] = path;
435 mVec[4] = "; ";
436 mVec[5] = XrdSysE2T(rc);
437 if (rc == EPERM) mVec[k++] = " because of excessive permissions";
438
439
440 if (erp) erp->setErrInfo(rc, mVec, k);
441 else {for (int k = 0; k < 6; k++) std::cerr <<mVec[k];
442 std::cerr <<"\n" <<std::flush;
443 }
444
445 return 0;
446}
447
448/******************************************************************************/
449/* Private: r e a d T o k e n */
450/******************************************************************************/
451
452XrdSecCredentials *XrdSecProtocolztn::readToken(XrdOucErrInfo *erp,
453 const char *path, bool &isbad)
454{
455 struct stat Stat;
456 const char *bTok;
457 char *buff;
458 int rdLen, sz, tokFD;
459
460// Be pessimistic
461//
462 isbad = true;
463
464// Get the size of the file
465//
466 if (stat(path, &Stat))
467 {if (errno != ENOENT) return readFail(erp, path, errno);
468 isbad = false;
469 return 0;
470 }
471
472// Make sure token is not too big
473//
474 if (Stat.st_size > maxTSize) return readFail(erp, path, EMSGSIZE);
475 buff = (char *)alloca(Stat.st_size+1);
476
477// Open the token file
478//
479 if ((tokFD = open(path, O_RDONLY)) < 0)
480 return readFail(erp, path, errno);
481
482// Read in the token
483//
484 if ((rdLen = read(tokFD, buff, Stat.st_size)) != Stat.st_size)
485 {int rc = (rdLen < 0 ? errno : EIO);
486 close(tokFD);
487 return readFail(erp, path, rc);
488 }
489 close(tokFD);
490
491// Make sure the token ends with a null byte
492//
493 buff[Stat.st_size] = 0;
494
495// Strip the token
496//
497 if (!(bTok = Strip(buff, sz)))
498 {isbad = false;
499 return 0;
500 }
501
502// Make sure the file is not accessible to anyone but the owner
503//
504 if (Stat.st_mode & (S_IRWXG | S_IRWXO)) return readFail(erp, path, EPERM);
505
506// Return response
507//
508 return retToken(erp, bTok, sz);
509}
510
511/******************************************************************************/
512/* Private: r e t T o k e n */
513/******************************************************************************/
514
515XrdSecCredentials *XrdSecProtocolztn::retToken(XrdOucErrInfo *erp,
516 const char *tkn, int tsz)
517{
518 TokenResp *tResp;
519 int rspLen = sizeof(TokenResp) + tsz + 1;
520
521// Make sure token is not too big
522//
523 if (tsz >= maxTSize) return Fatal(erp, "Token is too big", EMSGSIZE);
524
525// Verify that this is actually a JWT if so wanted
526//
527 if (verJWT && !XrdSecztn::isJWT(tkn)) return 0;
528
529// Get sufficient storage to assemble the full response
530//
531 tResp = (TokenResp *)malloc(rspLen);
532 if (!tResp)
533 {Fatal(erp, "Insufficient memory.", ENOMEM);
534 return 0;
535 }
536
537// Fill out the response
538//
539 tResp->hdr.Fill(TokenHdr::IsTkn);
540 tResp->len = htons(tsz+1);
541 memcpy(tResp->tkn, tkn, tsz);
542 *((tResp->tkn)+tsz) = 0;
543
544// Now return it
545//
546 return new XrdSecCredentials((char *)tResp, rspLen);
547}
548
549/******************************************************************************/
550/* Private: S t r i p */
551/******************************************************************************/
552
553const char *XrdSecProtocolztn::Strip(const char *bTok, int &sz)
554{
555 int j, k, n = strlen(bTok);
556
557// Make sure we have at least one character here
558//
559 if (!n) return 0;
560
561// Find first non-whitespace character
562//
563 for (j = 0; j < n; j++) if (!isspace(static_cast<int>(bTok[j]))) break;
564
565// Make sure we have at least one character
566//
567 if (j >= n) return 0;
568
569// Find last non-whitespace character
570//
571 for (k = n-1; k > j; k--) if (!isspace(static_cast<int>(bTok[k]))) break;
572
573// Compute length and allocate enough storage to copy the token
574//
575 if (k <= j) return 0;
576
577// Compute length and return pointer to the token
578//
579 sz = k - j + 1;
580 return bTok + j;
581}
582
583/******************************************************************************/
584/* S e r v e r O r i e n t e d M e t h o d s */
585/******************************************************************************/
586/******************************************************************************/
587/* A u t h e n t i c a t e */
588/******************************************************************************/
589
591 XrdSecParameters **parms,
592 XrdOucErrInfo *erp)
593{
594 static const int pfxLen = sizeof(TokenHdr) + sizeof(uint16_t);
595 TokenResp *tResp;
596
597// Check if we have any credentials or if no credentials really needed.
598// In either case, use host name as client name
599//
600 if (cred->size < (int)sizeof(TokenHdr) || !cred->buffer)
601 {Fatal(erp, "Invalid ztn credentials", EINVAL, false);
602 return -1;
603 }
604 tResp = (TokenResp *)cred->buffer;
605
606// Check if this is our protocol
607//
608 if (strcmp(tResp->hdr.id, "ztn"))
609 {char msg[256];
610 snprintf(msg, sizeof(msg),
611 "Authentication protocol id mismatch ('ztn' != '%.4s').",
612 tResp->hdr.id);
613 Fatal(erp, msg, EINVAL, false);
614 return -1;
615 }
616
617// Check if caller wants the list of authorized issuers
618//
619 if (tResp->hdr.opr == TokenHdr::SndAI) return SendAI(erp, parms);
620
621// If this is not a token response then this is an error
622//
623 if (tResp->hdr.opr != TokenHdr::IsTkn)
624 {Fatal(erp, "Invalid ztn response code", EINVAL, false);
625 return -1;
626 }
627
628// Make sure the response is consistent
629//
630 const char *isBad = 0;
631 int tLen = ntohs(tResp->len);
632
633 if (tResp->hdr.ver != ztnVersion) isBad = "version mismatch";
634 else if (tLen < 1) isBad = "token length < 1";
635 else if (pfxLen + tLen > cred->size) isBad = "respdata > credsize";
636 else if (!(tResp->tkn[0])) isBad = "null token";
637 else if (*(tResp->tkn+(tLen-1))) isBad = "missing null byte";
638
639 if (isBad)
640 {char eText[80];
641 snprintf(eText, sizeof(eText), "'ztn' token malformed; %s", isBad);
642 Fatal(erp, eText, EINVAL, false);
643 return -1;
644 }
645
646// Validate the token
647//
648 std::string msgRC;
649 long long eTime;
650 bool validated = false;
651 if (Entity.name) {free(Entity.name); Entity.name = 0;}
652 if (tokenlib && sthP->Validate(tResp->tkn, msgRC, (expiry ? &eTime : 0), &Entity))
653 {if (expiry)
654 {if (eTime < 0 && expiry > 0)
655 {Fatal(erp, "'ztn' token expiry missing", EINVAL, false);
656 return -1;
657 }
658 if ((monotonic_time() - eTime) <= 0)
659 {Fatal(erp, "'ztn' token expired", EINVAL, false);
660 return -1;
661 }
662 }
663 validated = true;
664 }
665 if (!tokenlib || validated)
666 {
667 Entity.credslen = strlen(tResp->tkn);
668 if (Entity.creds)
669 free(Entity.creds);
670 if ((Entity.creds = (char *)malloc(Entity.credslen+1)))
671 strcpy(Entity.creds, tResp->tkn);
672 else
673 Fatal(erp, "'ztn' bad alloc", ENOMEM, false);
674 if (!Entity.name) Entity.name = strdup("anon");
675 return 0;
676 }
677
678// Validation failed, generate message and return failure
679//
680// msgRC.insert(0, "ztn validation failed; ");
681 Fatal(erp, msgRC.c_str(), EAUTH, false);
682 return -1;
683}
684
685/******************************************************************************/
686/* Private: S e n d A I */
687/******************************************************************************/
688
689int XrdSecProtocolztn::SendAI(XrdOucErrInfo *erp, XrdSecParameters **parms)
690{
691 Fatal(erp, "Authorized issuer request not supported", ENOTSUP);
692 return -1;
693}
694
695/******************************************************************************/
696/* I n i t i a l i z a t i o n F u n c t i o n s */
697/******************************************************************************/
698/******************************************************************************/
699/* X r d S e c P r o t o c o l z t n I n i t */
700/******************************************************************************/
701
702extern "C"
703{
704char *XrdSecProtocolztnInit(const char mode,
705 const char *parms,
706 XrdOucErrInfo *erp)
707{
708 static char nilstr = 0;
709 XrdOucString accPlugin("libXrdAccSciTokens.so");
711
712// This only makes sense for server initialization
713//
714 if (mode == 'c') return &nilstr;
715
716// If there are no parameters, return the defaults
717//
718 if (!parms || !(*parms))
719 {char buff[256];
720 if (!getLinkage(erp, accPlugin.c_str())) return 0;
721 snprintf(buff, sizeof(buff), "TLS:%" PRIu64 ":%d:", opts, MaxTokSize);
722 return strdup(buff);
723 }
724
725// Copy the parameters as we will need modify them
726//
727 std::vector<XrdOucString> useVec;
728 XrdOucString cfgParms(parms);
729 XrdOucTokenizer cfg(const_cast<char *>(cfgParms.c_str()));
730 char *endP, *val;
731
732// Setup to parse parameters
733//
734 cfg.GetLine();
735
736// Parse the parameters: -expiry {none|optional|required} -maxsz <num>
737// -tokenlib <libpath>
738//
739 while((val = cfg.GetToken()))
740 { if (!strcmp(val, "-maxsz"))
741 {if (!(val = cfg.GetToken()))
742 {Fatal(erp, "-maxsz argument missing", EINVAL);
743 return 0;
744 }
745 MaxTokSize = strtol(val, &endP, 10);
746 if (*endP == 'k' || *endP == 'K')
747 {MaxTokSize *= 1024; endP++;}
748 if (MaxTokSize <= 0 || MaxTokSize > 524288 || *endP)
749 {Fatal(erp, "-maxsz argument is invalid", EINVAL);
750 return 0;
751 }
752 }
753 else if (!strcmp(val, "-expiry"))
754 {if (!(val = cfg.GetToken()))
755 {Fatal(erp, "-expiry argument missing", EINVAL);
756 return 0;
757 }
758 if (strcmp(val, "ignore")) expiry = 0;
759 else if (strcmp(val, "optional")) expiry = -1;
760 else if (strcmp(val, "required")) expiry = 1;
761 else {Fatal(erp, "-expiry argument invalid", EINVAL);
762 return 0;
763 }
764 }
765
766 else if (!strcmp(val, "-tokenlib"))
767 {if (!(val = cfg.GetToken()))
768 {Fatal(erp, "-acclib plugin path missing", EINVAL);
769 return 0;
770 }
771 if (strcmp(val,"none"))
772 {accPlugin = val;
773 }
774 else
775 {tokenlib = false;
776 }
777 }
778
779 else {XrdOucString eTxt("Invalid parameter - "); eTxt += val;
780 Fatal(erp, eTxt.c_str(), EINVAL);
781 return 0;
782 }
783 }
784
785// We rely on the token authorization plugin to validate tokens unless
786// it is disabled using '-tokenlib none'. If active load it to
787// get the validation object pointer. This will be filled in later but we
788// want to know that it's actually present.
789//
790 if (tokenlib && !getLinkage(erp, accPlugin.c_str())) return 0;
791
792// Assemble the parameter line and return it
793//
794 char buff[256];
795 snprintf(buff, sizeof(buff), "TLS:%" PRIu64 ":%d:", opts, MaxTokSize);
796 return strdup(buff);
797}
798}
799
800/******************************************************************************/
801/* X r d S e c P r o t o c o l z t n O b j e c t */
802/******************************************************************************/
803
804extern "C"
805{
807 const char *hostname,
808 XrdNetAddrInfo &endPoint,
809 const char *parms,
810 XrdOucErrInfo *erp)
811{
812 XrdSecProtocolztn *protP;
813
814// Whether this is a client of server, the connection must be using TLS.
815//
816 if (!endPoint.isUsingTLS())
817 {Fatal(erp,"security protocol 'ztn' disallowed for non-TLS connections.",
818 ENOTSUP, false);
819 return 0;
820 }
821
822// Get a protocol object appropriate for the mode
823//
824 if (mode == 'c')
825 {bool aOK;
826 protP = new XrdSecProtocolztn(parms, erp, aOK);
827 if (aOK) return protP;
828 delete protP;
829 return 0;
830 }
831
832 XrdSciTokensHelper *sthP= nullptr;
833 if (tokenlib)
834 {
835// In server mode we need to make sure the token plugin was actually
836// loaded and initialized as we need a pointer to the helper.
837//
838 sthP= *sth_Linkage;
839 if (!sthP)
840 {char msg[1024];
841 snprintf(msg,sizeof(msg),"ztn required plugin (%s) has not been loaded!",
842 sth_piName);
843 Fatal(erp, msg, EIDRM,false);
844 return 0;
845 }
846 }
847
848// Get an authentication object and return it
849//
850 if (!(protP = new XrdSecProtocolztn(hostname, endPoint, sthP)))
851 Fatal(erp, "insufficient memory for protocol.", ENOMEM, false);
852
853// All done
854//
855 return protP;
856}
857}
struct stat Stat
Definition XrdCks.cc:49
void Fatal(const char *op, const char *target)
Definition XrdCrc32c.cc:58
#define close(a)
Definition XrdPosix.hh:43
#define open
Definition XrdPosix.hh:71
#define stat(a, b)
Definition XrdPosix.hh:96
#define read(a, b, c)
Definition XrdPosix.hh:77
XrdSecBuffer XrdSecCredentials
#define EAUTH
XrdVERSIONINFO(XrdSecProtocolztnObject, secztn)
XrdSecProtocol * XrdSecProtocolztnObject(const char mode, const char *hostname, XrdNetAddrInfo &endPoint, const char *parms, XrdOucErrInfo *erp)
char * XrdSecProtocolztnInit(const char mode, const char *parms, XrdOucErrInfo *erp)
#define eMsg(x)
struct myOpts opts
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:104
char * Get(const char *varname)
Definition XrdOucEnv.hh:69
XrdOucEnv * getEnv()
int setErrInfo(int code, const char *emsg)
const char * c_str() const
char * GetToken(char **rest=0, int lowcase=0)
virtual bool Validate(const char *token, std::string &emsg, long long *expT=0, XrdSecEntity *entP=0)=0
int credslen
Length of the 'creds' data.
XrdNetAddrInfo * addrInfo
Entity's connection details.
char * creds
Raw entity credentials or cert.
char * name
Entity's name.
char * host
Entity's host name dnr dependent.
XrdSecEntity Entity
int Authenticate(XrdSecCredentials *cred, XrdSecParameters **parms, XrdOucErrInfo *einfo=0)
bool needTLS()
Check if this protocol requires TLS to properly function.
XrdSecProtocolztn(const char *hname, XrdNetAddrInfo &endPoint, XrdSciTokensHelper *sthp)
static const int ztnVersion
XrdSecCredentials * getCredentials(XrdSecParameters *parms, XrdOucErrInfo *einfo=0)
void Delete()
Delete the protocol object. DO NOT use C++ delete() on this object.
XrdSecProtocolztn(const char *parms, XrdOucErrInfo *erp, bool &aOK)
bool isJWT(const char *)
Definition XrdSecztn.cc:138
Generic structure to pass security information back and forth.
char * buffer
Pointer to the buffer.
int size
Size of the buffer or length of data in the buffer.