xrootd
XrdSecInterface.hh
Go to the documentation of this file.
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    The following extern "C" function must exist in your shared library.
00280 
00281 extern "C"
00282 {
00283        XrdSecProtocol *XrdSecGetProtocol(const char             *hostname,
00284                                          const struct sockaddr  &netaddr,
00285                                                XrdSecParameters &parms,
00286                                                XrdOucErrInfo    *einfo=0)
00287                                         {....}
00288 }
00289 
00290    MT Requirements: Must be MT_Safe.
00291 */
00292  
00293 /******************************************************************************/
00294 /*                         X r d S e c S e r v i c e                          */
00295 /*                                                                            */
00296 /*                  S e r v e r   S i d e   U s e   O n l y                   */
00297 /******************************************************************************/
00298   
00299 // The XrdSecService object is the the object that the server uses to obtain
00300 // parameters to be passed to the client on initial contact and to create the
00301 // appropriate protocol on the initial receipt of the client's credentials.
00302 // Server-side processing is a bit more complicated because the set of valid
00303 // protocols needs to be configured and that configuration needs to be supplied
00304 // to the client so that both can agree on a compatible protocol. This object
00305 // is created via a call to XrdSecgetService, defined later on.
00306   
00307 class XrdSecService
00308 {
00309 public:
00310 
00311 // = 0 -> No security parameters need to be supplied to the client.
00312 //        This implies that authentication need not occur.
00313 // ! 0 -> Address of the parameter string (which may be host-specigfic if hname
00314 //        was supplied). Ths length of the string is returned in size.
00315 //
00316 virtual const char     *getParms(int &size, const char *hname=0) = 0;
00317 
00318 // = 0 -> No protocol can be returned (einfo has the reason)
00319 // ! 0 -> Address of protocol object is bing returned. If cred is null,
00320 //        a host protocol object is returned if so allowed.
00321 //
00322 virtual XrdSecProtocol *getProtocol(const char              *host,    // In
00323                                     const struct sockaddr   &hadr,    // In
00324                                     const XrdSecCredentials *cred,    // In
00325                                     XrdOucErrInfo           *einfo)=0;// Out
00326 
00327                         XrdSecService() {}
00328 virtual                ~XrdSecService() {}
00329 };
00330 
00331 // MT Requirements: Must be MT_Safe.
00332   
00333 /******************************************************************************/
00334 /*                      X r d g e t S e c S e r v i c e                       */
00335 /******************************************************************************/
00336 
00337 /* The XrdSecSgetService function is called during server initialization to
00338    obtain the XrdSecService object. This function must be defined in your
00339    shared library and is used by the server to obtain an XrdSecService object
00340    used by the server to control server-side authentication.
00341 
00342 extern "C"
00343 {
00344        XrdSecService *XrdSecgetService(XrdSysLogger *lp, const char *cfn) {....}
00345 }
00346 
00347    MT Requirements: None. Function called once in single-thread mode.
00348 */
00349 #endif