/******************************************************************************/ /* */ /* X r d S e c t e s t S e r v e r . c c */ /* */ /* (c) 2003 by the Board of Trustees of the Leland Stanford, Jr., University */ /* All Rights Reserved */ /* Produced by Andrew Hanushevsky for Stanford University under contract */ /* DE-AC02-76-SFO0515 with the Department of Energy */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ #include #include #include #include #include #include #include #include "XrdNet/XrdNetAddr.hh" #include "XrdOuc/XrdOucErrInfo.hh" #include "XrdSys/XrdSysHeaders.hh" #include "XrdSys/XrdSysLogger.hh" #include "XrdSec/XrdSecInterface.hh" /******************************************************************************/ /* L O C A L D E F I N I T I O N S */ /******************************************************************************/ #define H(x) fprintf(stderr,x); fprintf(stderr, "\n"); #define I(x) fprintf(stderr, "\n"); H(x) #define insx(a,b) sprintf(errbuff,a,b) #define insy(a,b,c) sprintf(errbuff,a,b,c) typedef unsigned char uchar; /******************************************************************************/ /* g l o b a l v a r i a b l e s */ /******************************************************************************/ /* Define the execution control structure. */ struct myOpts { int debug; /* 1 -> Enable debugging. */ int bin; /* 1 -> Input cred in binary format. */ int xtra; /* 1 -> Perform null cred test */ int online; /* 1 -> Filename is actual hex cred. */ char *cfn; /* -> config file */ char *host; /* -> hostname */ char *inpt; /* -> Input stream name. */ FILE *infid; /* -> Input stream (normally stdin). */ } opts; /* Define global variables. */ char errbuff[256]; #ifndef C_Block char hexbuff[256]; #else char hexbuff[sizeof(C_Block)+8]; #endif extern "C" { extern XrdSecService *XrdSecgetService(XrdSysLogger *lp, const char *cfn); } /******************************************************************************/ /* f u n c t i o n d e f i n i t i o n s */ /******************************************************************************/ int getbintix(uchar *buff, int blen); void getargs(int argc, char **argv); int unhex(uchar *ibuff, uchar *obuff, int blen); int cvtx(uchar idig, uchar *odig); void getline(uchar *buff, int blen); char *Ereason( ); int emsg(int rc,char *msg); void help(int rc); void xerr(int x); /******************************************************************************/ /* M A I N P R O G R A M */ /******************************************************************************/ int main(int argc, char **argv) { XrdNetAddr theAddr; XrdOucErrInfo einfo; XrdSysLogger Logger; XrdSecService *ServerSecurity; XrdSecParameters *parmp; XrdSecCredentials cred((char *)malloc(8192), 8192); XrdSecProtocol *pp; const char *eText; unsigned char bbuff[4096]; int i, rc; // Parse the argument list. // getargs(argc, argv); // if hostname given, get the hostname address // if (opts.host) {if ((eText = theAddr.Set(opts.host,0))) {cerr <<"testServer: Unable to resolve '" <getParms(i, opts.host); if (!sect) cerr <<"testServer: No security token for " <getProtocol(opts.host, theAddr, (const XrdSecCredentials *)&cred, &einfo))) {rc = einfo.getErrInfo(); cerr << "testServer: getProtocol error " <Authenticate(&cred, &parmp, &einfo) < 0) {rc = einfo.getErrInfo(); cerr << "testServer: Authenticate error " <Entity.name ? pp->Entity.name : "?") <<"@" <<(pp->Entity.host ? pp->Entity.host : "?") <<" prot=" <Entity.prot <= 0) buff[i] = (uchar)j; else if (j == EOF) return i; else xerr(insx("Error reading cred; %s.", Ereason())); xerr(insx("Cred longer than %d bytes.", blen)); return -1; } /******************************************************************************/ /* Command Line Processing */ /******************************************************************************/ /* getargs: parse through argv obtaining options and parameters. */ void getargs(int argc, char **argv) { extern int optind; extern char *optarg; char c; /* Establish defaults here. */ opts.debug = 0; opts.bin = 0; opts.online = 0; opts.cfn = 0; opts.host = 0; opts.xtra = 0; opts.inpt = (char *)""; opts.infid = stdin; opts.cfn = 0; /* Process the options */ while ((c=getopt(argc,argv,"c:h:i:k:p:bdx")) != (char)EOF) { switch(c) { case 'b': opts.bin = 1; break; case 'c': opts.cfn = optarg; break; case 'd': opts.debug = 1; break; case 'h': opts.host = optarg; break; case 'i': opts.inpt = optarg; break; case 'x': opts.xtra = 1; break; case '?': help(1); } } /*Get the credentials, if specified on the command line. */ if (optind < argc) {opts.inpt = argv[optind++]; opts.online = 1;} /*Make sure no more parameters exist. */ if (optind < argc) xerr(insx("Extraneous parameter, '%s'.", argv[optind])); /*If the input stream is other than stdin, verify that it exists. */ if (opts.inpt[0] != '\000' && !opts.online && (!(opts.infid = fopen(opts.inpt, "r"))) ) xerr(insy("Cannot open '%s'; %s.", opts.inpt, Ereason() )); /* Make sure that -i * and -b are not specified together. */ if (opts.online && opts.bin) emsg(8, (char *)"-b is incompatible with inline creds."); /*All done */ return; } /******************************************************************************/ /* Utility Function */ /******************************************************************************/ /* unhex() converts a hex character string to its binary equivalent. The result is placed in the passed buffer. It returns the number of bytes extracted. An error results in a -1 response (including uneven hex digits). The input buffer must be terminated with a null. */ int unhex(uchar *ibuff, uchar *obuff, int blen) { int i=0, j; uchar dig1, dig2; for (j = 0; j < blen; j++) { if (!ibuff[i]) return j; if (!cvtx(ibuff[i++], &dig1) || !cvtx(ibuff[i++], &dig2)) return -1; obuff[j] = (dig1 << 4) | dig2; } return -1; /* Buffer overflow */ } int cvtx(uchar idig, uchar *odig) { if (idig >= '0' && idig <= '9') {*odig = idig & (uchar)0x0f; return 1;} idig = idig | (uchar)0x20; /* Change to lower case. */ if (idig < 'a' || idig > 'f') return 0; *odig = (idig & (uchar)0x0f) + (uchar)0x09; return 1; } /*getline() gets a newline terminated string from the expected input source. */ void getline(uchar *buff, int blen) { int i; if (!fgets((char *)buff, blen, opts.infid)) return; for (i = 0; i < blen; i++) if (buff[i] == '\n') {buff[i] = '\000'; break;} return; } char *Ereason( ) { return strerror(errno); } /*xerr: print message on standard error using the errbuff as source of message. */ void xerr(int x) { emsg(8, errbuff); } /*emsg: print message on standard error. */ int emsg(int rc,char *msg) { cerr << "testServer: " < 1) exit(rc); I("options: (defaults: -k /etc/srvtab\\n") I("-b indicates the cred is in binary format (i.e., not hexchar).") I("-c cfn the config file.") I("-d turns on debugging.") I("-h host the incomming hostname.") I("-i input specifies the input stream (e.g., fname) if other than stdin.") H(" This -i is ignored if cred is specified on the command line.") exit(rc); }