00001 #ifndef __SEC_INTERFACE_H__ 00002 #define __SEC_INTERFACE_H__ 00003 /******************************************************************************/ 00004 /* */ 00005 /* X r d S e c I n t e r f a c e . h h */ 00006 /* */ 00007 /* (c) 2005 by the Board of Trustees of the Leland Stanford, Jr., University */ 00008 /* All Rights Reserved. See XrdInfo.cc for complete License Terms */ 00009 /* Produced by Andrew Hanushevsky for Stanford University under contract */ 00010 /* DE-AC03-76-SFO0515 with the Department of Energy */ 00011 /******************************************************************************/ 00012 00013 #include <errno.h> 00014 #ifndef WIN32 00015 #include <netdb.h> 00016 #include <netinet/in.h> 00017 #include <sys/param.h> 00018 #endif 00019 #include <stdlib.h> 00020 #include <stdio.h> 00021 #include <string.h> 00022 #if defined(__CYGWIN__) || defined(__FreeBSD__) 00023 #include <sys/socket.h> 00024 #endif 00025 00026 #include "XrdSec/XrdSecEntity.hh" 00027 00028 /******************************************************************************/ 00029 /* X r d S e c C r e d e n t i a l s & X r d S e c P a r a m e t e r s */ 00030 /******************************************************************************/ 00031 00032 // The following structure is used to pass security information back and forth 00033 // 00034 struct XrdSecBuffer 00035 { 00036 int size; 00037 char *buffer; 00038 00039 XrdSecBuffer(char *bp=0, int sz=0) : size(sz), buffer(bp), membuf(bp) {} 00040 ~XrdSecBuffer() {if (membuf) free(membuf);} 00041 00042 private: 00043 char *membuf; 00044 }; 00045 00046 // When the buffer is used for credentials, the start of the buffer always 00047 // holds the credential protocol name (e.g., krb4) as a string. The client 00048 // will get credentials and the size will be filled out so that the contents 00049 // of buffer can be easily transmitted to the server. 00050 // 00051 typedef XrdSecBuffer XrdSecCredentials; 00052 00053 // When the buffer is used for parameters, the contents must be interpreted 00054 // in the context that it is used. For instance, the server will send the 00055 // security configuration parameters on the initial login. The format differs 00056 // from. say, the x.500 continuation paremeters that would be sent during 00057 // PKI authentication via an "authmore" return status. 00058 // 00059 typedef XrdSecBuffer XrdSecParameters; 00060 00061 /******************************************************************************/ 00062 /* X r d S e c P r o t o c o l */ 00063 /******************************************************************************/ 00064 00065 // The XrdSecProtocol is used to generate authentication credentials and to 00066 // authenticate those credentials. For example, When a server indicates 00067 // that authentication is needed (i.e., it returns security parameters), the 00068 // client must call XrdSecgetProtocol() to get an appropriate XrdSecProtocol 00069 // (i.e., one specific to the authentication protocol that needs to be used). 00070 // Then the client can use the first form getCredentials() to generate the 00071 // appropriate identification information. On subsequent calls in response to 00072 // "authmore" the client must use the second form, providing the additional 00073 // parameters the the server sends. The server uses Authenticate() to verify 00074 // the credentials. When XrdOucErrInfo is null (as it will usually be), error 00075 // messages are routed to standard error. So, for example, a client would 00076 00077 // 1) Call XrdSecGetProtocol() to get an appropriate XrdSecProtocol 00078 // (i.e., one specific to the authentication protocol that needs to be used). 00079 // Note that successive calls to XrdSecGetProtocol() using the same 00080 // XrdSecParameters will use the subsequent protocol named in the list of 00081 // protocols that the server returned. Failure is indicated when the list 00082 // is exhausted or none of the protocols apply (which exhausts the list). 00083 00084 00085 // 2) Call getCredentials() without supplying any parameters so as to 00086 // generate identification information and send them to the server. 00087 00088 // 3) If the server indicates "authmore", call getCredentials() supplying 00089 // the additional parameters sent by the server. The returned credentials 00090 // are then sent to the server using the "authneticate" request code. 00091 00092 // 4) Repeat step (3) as often as "authmore" is requested by the server. 00093 00094 // The server uses Authenticate() to verify the credentials and getParms() 00095 // to generate initial parameters to start the authentication process. 00096 00097 // When XrdOucErrInfo is null (as it will usually be), error messages are 00098 // are routed to standard error. 00099 00100 // Server-side security is handled by the XrdSecServer object and, while 00101 // it uses XrdSecProtocol objects to perform authentication, the XrdSecServer 00102 // object is used to initialize the security environment and to generate 00103 // the appropriate protocol objects at run-time. See XrdSecServer.hh. 00104 00105 // MT Requirements: Must be MT_Safe. 00106 00107 class XrdOucErrInfo; 00108 00109 class XrdSecProtocol 00110 { 00111 public: 00112 00113 // The following structure holds the entity's identification. It is filled 00114 // in by a successful call to Authenticate(). 00115 // 00116 XrdSecEntity Entity; 00117 00118 // Authenticate credentials supplied by the client or server. Upon success, 00119 // the XrdSecIdentity structure is completed. The method returns: 00120 // 00121 // > 0 -> parms present (more authentication needed) 00122 // = 0 -> client present (authentication suceeded) 00123 // < 0 -> einfo present (error has occured) 00124 // 00125 virtual int Authenticate (XrdSecCredentials *cred, 00126 XrdSecParameters **parms, 00127 XrdOucErrInfo *einfo=0)=0; 00128 00129 // Generate credentials to be used in the authentication process. Upon 00130 // success, return a credentials object. Upon failure, returns null and 00131 // einfo, if present, has the reason for the failure. 00132 // 00133 virtual XrdSecCredentials *getCredentials(XrdSecParameters *parm=0, 00134 XrdOucErrInfo *einfo=0)=0; 00135 00136 // Encrypt data in inbuff and place it in outbuff. 00137 // 00138 // Returns: < 0 Failed, the return value is -errno of the reason. Typically, 00139 // -EINVAL - one or more arguments are invalid. 00140 // -NOTSUP - encryption not supported by the protocol 00141 // -EOVERFLOW - outbuff is too small to hold result 00142 // -ENOENT - Context not innitialized 00143 // = 0 Success, outbuff contains a pointer to the encrypted data. 00144 // 00145 virtual int Encrypt(const char * /*inbuff*/, // Data to be encrypted 00146 int /*inlen*/, // Length of data in inbuff 00147 XrdSecBuffer ** /*outbuff*/ // Returns encrypted data 00148 ) {return -ENOTSUP;} 00149 00150 // Decrypt data in inbuff and place it in outbuff. 00151 // 00152 // Returns: < 0 Failed,the return value is -errno (see Encrypt). 00153 // = 0 Success, outbuff contains a pointer to the encrypted data. 00154 // 00155 virtual int Decrypt(const char * /*inbuff*/, // Data to be decrypted 00156 int /*inlen*/, // Length of data in inbuff 00157 XrdSecBuffer ** /*outbuff*/ // Buffer for decrypted data 00158 ) {return -ENOTSUP;} 00159 00160 // Sign data in inbuff and place the signiture in outbuff. 00161 // 00162 // Returns: < 0 Failed, returned value is -errno (see Encrypt). 00163 // = 0 Success, the return value is the length of the signature 00164 // placed in outbuff. 00165 // 00166 virtual int Sign(const char * /*inbuff*/, // Data to be signed 00167 int /*inlen*/, // Length of data in inbuff 00168 XrdSecBuffer ** /*outbuff*/ // Buffer for the signature 00169 ) {return -ENOTSUP;} 00170 00171 // Verify a signature 00172 // 00173 // Returns: < 0 Failed, returned value is -errno (see Encrypt). 00174 // = 0 Signature matches the value in inbuff. 00175 // > 0 Failed to verify, signature does not match inbuff data. 00176 // 00177 virtual int Verify(const char * /*inbuff*/, // Data to be decrypted 00178 int /*inlen*/, // Length of data in inbuff 00179 const char * /*sigbuff*/, // Buffer for signature 00180 int /*siglen*/) // Length if signature 00181 {return -ENOTSUP;} 00182 00183 // Get the current encryption key 00184 // 00185 // Returns: < 0 Failed, returned value if -errno (see Encrypt) 00186 // >= 0 The size of the encyption key. The supplied buffer of length 00187 // size hold the key. If the buffer address is 0, only the 00188 // size of the key is returned. 00189 // 00190 virtual int getKey(char * /*buff*/=0, int /*size*/=0) {return -ENOTSUP;} 00191 00192 // Set the current encryption key 00193 // 00194 // Returns: < 0 Failed, returned value if -errno (see Encrypt) 00195 // 0 The new key has been set. 00196 // 00197 virtual int setKey(char * /*buff*/, int /*size*/) {return -ENOTSUP;} 00198 00199 // DO NOT use C++ delete() on this object. Since the same compiler may not 00200 // have been used in constructing all shared libraries, you must use the object 00201 // specific Delete() method to insure that the object creator's delete is used. 00202 // 00203 virtual void Delete()=0; // Normally does "delete this" 00204 00205 XrdSecProtocol(const char *pName) : Entity(pName) {} 00206 protected: 00207 00208 virtual ~XrdSecProtocol() {} 00209 }; 00210 00211 /******************************************************************************/ 00212 /* P r o t o c o l N a m i n g C o n v e n t i o n s */ 00213 /******************************************************************************/ 00214 00215 // Each specific protocol resides in a shared library named "libXrdSec<p>.so" 00216 // where <p> is the protocol identifier (e.g., krb5, gsi, etc). The library 00217 // contains a class derived from the XrdSecProtocol object. The library must 00218 // also contain a two extern "C" functions: 00219 // 1) XrdSec<p>Init() - for one-time protocol ininitialization, and 00220 // 2) XrdSec<p>Object() - for protocol object instantiation. 00221 // 00222 // extern "C" {char *XrdSecProtocol<p>Init (const char who, 00223 // const char *parms, 00224 // XrdOucErrInfo *einfo); 00225 // } 00226 // Is used by the dynamic protocol loader to initialize the protocol when the 00227 // shared library is loaded. Parmater who contains 'c' when called on the 00228 // client side and 's' when called on the server side. For client initialization, 00229 // the parms is null. For server size initialization, parms contains the 00230 // parameters specified in the configuration file. The protocol must return 00231 // the parameters it needs to have sent to the client during the initial 00232 // authentication handshake. If no parameters need to be sent, it must return 00233 // the null string. If initialization fails, null must be returned and einfo 00234 // must contain the reason for the failure. The storage occupied by the returned 00235 // string is not freed by the dynamic loader; therefore, constant strings can 00236 // be returned. 00237 00238 // MT Requirements: None. Function called once in single-thread mode. 00239 00240 // extern "C" { 00241 // XrdSecProtocol *XrdSecProtocol<p>Object(const char who, 00242 // const char *hostname, 00243 // const struct sockaddr &netaddr, 00244 // const char *parms, 00245 // XrdOucErrInfo *einfo); 00246 // } 00247 // Is used by the dynamic protocol loader to obtain an instance of the 00248 // XrdSecProtocol object. Argument who will contain 'c' for client-side calls 00249 // and 's' for server-side calls. When who = 'c' then parms contains the parms 00250 // supplied by the protocol at server-side initialization time (see the 00251 // function Xrdsec<p>Init*(, explained above). When who = 's', parms is null. 00252 00253 // Warning! The protocol *must* allow both 'c' and 's' calls to occur within 00254 // the same execution context. This occurs when a server acts like a client. 00255 00256 // The naming conventions were chosen to avoid platform dependent run-time 00257 // loaders that resolve all addresses with the same name in all shared libraries 00258 // to the first address with the same name encountered by the run-time loader. 00259 00260 // MT Requirements: Must be MT_Safe. 00261 00262 /******************************************************************************/ 00263 /* X r d S e c G e t P r o t o c o l */ 00264 /* */ 00265 /* C l i e n t S i d e U S e O n l y */ 00266 /******************************************************************************/ 00267 00268 // The following external routine creates a security context and returns an 00269 // XrdSecProtocol object to be used for authentication purposes. The caller 00270 // provides the host name and IP address of the remote connection along with 00271 // any parameters provided by the server. A null return means an error occured. 00272 // Error messages are sent to standard error unless and XrdOucErrInfo class is 00273 // provided to capture the message. There should be one protocol object per 00274 // physical TCP/IP connection. 00275 00276 // When the connection is closed, the protocol's Delete() method should be 00277 // called to properly delete the object. 00278 // 00279 extern "C" 00280 { 00281 extern XrdSecProtocol *XrdSecGetProtocol(const char *hostname, 00282 const struct sockaddr &netaddr, 00283 XrdSecParameters &parms, 00284 XrdOucErrInfo *einfo=0); 00285 } 00286 00287 // MT Requirements: Must be MT_Safe. 00288 00289 /******************************************************************************/ 00290 /* X r d S e c S e r v i c e */ 00291 /* */ 00292 /* S e r v e r S i d e U s e O n l y */ 00293 /******************************************************************************/ 00294 00295 // The XrdSecService object is the the object that the server uses to obtain 00296 // parameters to be passed to the client on initial contact and to create the 00297 // appropriate protocol on the initial receipt of the client's credentials. 00298 // Server-side processing is a bit more complicated because the set of valid 00299 // protocols needs to be configured and that configuration needs to be supplied 00300 // to the client so that both can agree on a compatible protocol. This object 00301 // is created via a call to XrdSecgetService, defined later on. 00302 00303 class XrdSecService 00304 { 00305 public: 00306 00307 // = 0 -> No security parameters need to be supplied to the client. 00308 // This implies that authentication need not occur. 00309 // ! 0 -> Address of the parameter string (which may be host-specigfic if hname 00310 // was supplied). Ths length of the string is returned in size. 00311 // 00312 virtual const char *getParms(int &size, const char *hname=0) = 0; 00313 00314 // = 0 -> No protocol can be returned (einfo has the reason) 00315 // ! 0 -> Address of protocol object is bing returned. If cred is null, 00316 // a host protocol object is returned if so allowed. 00317 // 00318 virtual XrdSecProtocol *getProtocol(const char *host, // In 00319 const struct sockaddr &hadr, // In 00320 const XrdSecCredentials *cred, // In 00321 XrdOucErrInfo *einfo)=0;// Out 00322 00323 XrdSecService() {} 00324 virtual ~XrdSecService() {} 00325 }; 00326 00327 // MT Requirements: Must be MT_Safe. 00328 00329 /******************************************************************************/ 00330 /* X r d g e t S e c S e r v i c e */ 00331 /******************************************************************************/ 00332 00333 // The XrdSecSgetService function is calle during server initialization to 00334 // obtain the XrdSecService object. This object is used to control server-side 00335 // authentication. 00336 // 00337 class XrdSysLogger; 00338 00339 extern "C" 00340 { 00341 extern XrdSecService *XrdSecgetService(XrdSysLogger *lp, const char *cfn); 00342 } 00343 00344 // MT Requirements: None. Function called once in single-thread mode. 00345 #endif