Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Protected Member Functions | Static Protected Attributes | Private Member Functions | Private Attributes
Arc::HTTPSClientConnectorGSSAPI Class Reference

#include <HTTPSClient.h>

Inheritance diagram for Arc::HTTPSClientConnectorGSSAPI:
Inheritance graph
[legend]
Collaboration diagram for Arc::HTTPSClientConnectorGSSAPI:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 HTTPSClientConnectorGSSAPI (const char *base, bool heavy_encryption, int timeout=60000, gss_cred_id_t cred=GSS_C_NO_CREDENTIAL, bool check_host=true)
virtual ~HTTPSClientConnectorGSSAPI (void)
virtual bool credentials (gss_cred_id_t cred)

Protected Member Functions

virtual bool connect (bool &timedout)
 Establish connection and context (if needed)
virtual bool disconnect (void)
 Close connection to remote host.
virtual bool clear (void)
 Read all pending data.
virtual bool read (char *buf=NULL, unsigned int *size=NULL)
 Set buffer for reading data.
virtual bool write (const char *buf=NULL, unsigned int size=0)
 Set data to be sent.
virtual bool transfer (bool &read, bool &write, int timeout)
 Transfer data set by read() and write(). Reset set buffers if operation complete.
virtual bool eofread (void)
 If network connection was closed.
virtual bool eofwrite (void)
 If there is pending buffer set by write()

Static Protected Attributes

static SimpleConditionconnect_lock = new SimpleCondition()
 Lock for mutex on connection (bug 1613)
static Logger logger
 logger

Private Member Functions

int read_SSL_token (void **val, int timeout)
int do_read (char *buf, int size, int &timeout)
int do_write (char *buf, int size, int &timeout)

Private Attributes

bool valid
URL base_url
int s
gss_cred_id_t cred
gss_ctx_id_t context
int timeout
char * read_buf
unsigned int read_size
unsigned int * read_size_result
bool read_eof_flag
const char * write_buf
unsigned int write_size
bool check_host_cert

Detailed Description

Definition at line 147 of file HTTPSClient.h.


Constructor & Destructor Documentation

Arc::HTTPSClientConnectorGSSAPI::HTTPSClientConnectorGSSAPI ( const char *  base,
bool  heavy_encryption,
int  timeout = 60000,
gss_cred_id_t  cred = GSS_C_NO_CREDENTIAL,
bool  check_host = true 
)

Definition at line 370 of file HTTPSClientConnector.cpp.

                                                                                                                                                   : base_url(base), check_host_cert(check_host) {
    s=-1;
    cred=cred_;
    timeout=timeout_;
    context=GSS_C_NO_CONTEXT;
    valid=true;
  } catch(std::exception e) {
    valid=false;
  }

Definition at line 737 of file HTTPSClientConnector.cpp.

                                                              {
    disconnect();
  }

Here is the call graph for this function:


Member Function Documentation

bool Arc::HTTPSClientConnectorGSSAPI::clear ( void  ) [protected, virtual]

Read all pending data.

Reimplemented from Arc::HTTPSClientConnector.

Definition at line 722 of file HTTPSClientConnector.cpp.

                                             {
    gss_buffer_desc recv_tok;
    int l;
    while(true) {
      l=read_SSL_token(&(recv_tok.value),0);
      if(l <= 0) return true;
      if(recv_tok.value) free(recv_tok.value);
    };
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::HTTPSClientConnectorGSSAPI::connect ( bool &  timedout) [protected, virtual]

Establish connection and context (if needed)

??????????????

Reimplemented from Arc::HTTPSClientConnector.

Definition at line 380 of file HTTPSClientConnector.cpp.

                                                         {
    if(!valid) return false;
    if(s != -1) return true;
    read_buf=NULL; read_size=0; read_size_result=NULL;
    write_buf=NULL; write_size=0;
    read_eof_flag=false;
  
    struct addrinfo* res;
    int err;
    if((err=getaddrinfo(base_url.Host().c_str(),NULL,NULL,&res)) != 0) {
      logger.msg(ERROR, "Address resolution failed: %s", gai_strerror(err));
      return false;
    }
    struct addrinfo* r = res;
    for(;r;r=r->ai_next) {
      if(r->ai_addr == NULL) continue;
      if(r->ai_socktype != SOCK_STREAM) continue;
      if(r->ai_protocol != IPPROTO_TCP) continue;
      if(r->ai_family == AF_INET) {
        ((struct sockaddr_in*)(r->ai_addr))->sin_port=htons(base_url.Port());
        break;
      }
      if(r->ai_family == AF_INET6) {
        ((struct sockaddr_in6*)(r->ai_addr))->sin6_port=htons(base_url.Port());
        break;
      }
    }
    if(!r) {
      freeaddrinfo(res);
      logger.msg(ERROR, "Address resolution failed: %s", "no suitable address found");
      return false;
    }
    s=::socket(r->ai_family,r->ai_socktype,r->ai_protocol);
    if(s==-1) {
      freeaddrinfo(res);
      logger.msg(ERROR, "Socket creation failed: %s", Arc::StrError(errno));
      return false;
    };
  
    if(::connect(s,r->ai_addr,r->ai_addrlen)==-1) {
      freeaddrinfo(res);
      logger.msg(ERROR, "Connection to server failed: %s", Arc::StrError(errno));
      ::close(s); s=-1;
      return false;
    };
    freeaddrinfo(res);
  
    OM_uint32 major_status = 0;
    OM_uint32 minor_status = 0;
  
    //if(cred == GSS_C_NO_CREDENTIAL) {
    //  major_status = gss_acquire_cred(&minor_status,
    //                                  GSS_C_NO_NAME,
    //                                  0,
    //                                  GSS_C_NULL_OID_SET,
    //                                  GSS_C_ACCEPT,
    //                                  &cred,
    //                                  NULL,
    //                                  NULL);
    //  if (major_status != GSS_S_COMPLETE) {
    //    logger.msg(ERROR, "Failed to acquire local credentials");
    //    ::close(s); s=-1;
    //    return false;
    //  };
    //};
  
    OM_uint32 init_sec_min_stat;
    OM_uint32 ret_flags =  0;
    gss_name_t remote_name = GSS_C_NO_NAME;
    gss_OID oid = GSS_C_NO_OID; // ??????????
    gss_buffer_desc recv_tok;
    gss_buffer_desc send_tok;
    int context_flags = GSS_C_CONF_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | GSS_C_DELEG_FLAG; // GSS_C_GLOBUS_SSL_COMPATIBLE
  #ifdef HAVE_GLOBUS_GSS_ASSIST_AUTHORIZATION_HOST_NAME
    globus_gss_assist_authorization_host_name((char*)(base_url.Host().c_str()),&remote_name);
  #else
    {
      gss_buffer_desc name_tok;
      name_tok.value = (void*)(base_url.Host().c_str());
      name_tok.length = base_url.Host().length() + 1;
      major_status=gss_import_name(&minor_status,&name_tok,
                                   GSS_C_NT_HOSTBASED_SERVICE,&remote_name);
      // if(GSS_ERROR(major_status))
    };
  #endif
    // check if we want to do service host cert checks
    if(!check_host_cert) {
      remote_name=GSS_C_NO_NAME;
      // can't do delegation with no target host
      context_flags = GSS_C_CONF_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG;
    };
  
    recv_tok.length=0; recv_tok.value=NULL;
    send_tok.length=0; send_tok.value=NULL;
    connect_lock->lock();
    for(;;) {
      major_status = gss_init_sec_context(&init_sec_min_stat,
                                          cred,
                                          &context,
                                          remote_name,
                                          oid,
                                          context_flags,
                                          0,
                                          NULL,
                                      recv_tok.value?&recv_tok:GSS_C_NO_BUFFER,
                                          NULL,
                                          &send_tok,
                                          &ret_flags,
                                          NULL);
      if(recv_tok.value) { free(recv_tok.value); recv_tok.value=NULL; };
      if((major_status!=GSS_S_COMPLETE) &&
         (major_status!=GSS_S_CONTINUE_NEEDED)) {
        logger.msg(ERROR, "Failed to authenticate: %s", gss_error_string(major_status,init_sec_min_stat));
        ::close(s); s=-1; break;
      };
      if(context == NULL) {
        logger.msg(ERROR, "Failed to create GSI context: %s", gss_error_string(major_status,init_sec_min_stat));
        ::close(s); s=-1; break;
      };
      if(send_tok.length != 0) {
        int to = timeout;
        if(do_write((char*)(send_tok.value),send_tok.length,to) == -1) {
          ::close(s); s=-1; break;
        };
        gss_release_buffer(&minor_status,&send_tok); send_tok.length=0;
      };
      if(major_status==GSS_S_COMPLETE) break;
      int l=read_SSL_token(&(recv_tok.value),timeout);
      if(l <= 0) {
        logger.msg(ERROR, "Failed to read SSL token during authentication");
        if(context != GSS_C_NO_CONTEXT)
          gss_delete_sec_context(&minor_status,&context,GSS_C_NO_BUFFER);
        context=GSS_C_NO_CONTEXT;
        ::close(s); s=-1;
        connect_lock->unlock();
        return false;
      };
      recv_tok.length=l;
    };
    connect_lock->unlock();
    if(s == -1) {
      if(context != GSS_C_NO_CONTEXT) {
        gss_delete_sec_context(&minor_status,&context,GSS_C_NO_BUFFER);
        context=GSS_C_NO_CONTEXT;
      };
    };
    if(recv_tok.value) { free(recv_tok.value); recv_tok.value=NULL; };
    if(send_tok.length != 0) gss_release_buffer(&minor_status,&send_tok);
    if(remote_name != GSS_C_NO_NAME) gss_release_name(&minor_status,&remote_name);
    if(s == -1) {
    };
    return (s != -1);
  }

Here is the call graph for this function:

bool Arc::HTTPSClientConnectorGSSAPI::credentials ( gss_cred_id_t  cred) [virtual]

Reimplemented from Arc::HTTPSClientConnector.

Definition at line 732 of file HTTPSClientConnector.cpp.

                                                                  {
    cred=cred_;
    return true;
  }
bool Arc::HTTPSClientConnectorGSSAPI::disconnect ( void  ) [protected, virtual]

Close connection to remote host.

Reimplemented from Arc::HTTPSClientConnector.

Definition at line 535 of file HTTPSClientConnector.cpp.

                                                  {
    if(s == -1) return true;
    ::close(s); s=-1;
    OM_uint32 minor_status = 0;
    if(context != GSS_C_NO_CONTEXT)
      gss_delete_sec_context(&minor_status,&context,GSS_C_NO_BUFFER);
    context=GSS_C_NO_CONTEXT;
    return true;
  }  

Here is the caller graph for this function:

int Arc::HTTPSClientConnectorGSSAPI::do_read ( char *  buf,
int  size,
int &  timeout 
) [private]

Definition at line 663 of file HTTPSClientConnector.cpp.

                                                                         {
    int n = size;
    for(;n;) {
      if(!waitsocket(s,-1,timeout)) return -1;
      int l = ::recv(s,buf,n,0);
      if((l == -1) && (errno != EINTR)) return -1;
      if(l == 0) {
        if(n == size) return 0;
        return -1;
      };
      buf+=l; n-=l;
    };
    return size;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

int Arc::HTTPSClientConnectorGSSAPI::do_write ( char *  buf,
int  size,
int &  timeout 
) [private]

Definition at line 678 of file HTTPSClientConnector.cpp.

                                                                          {
    int n = size;
    for(;n;) {
      if(!waitsocket(-1,s,timeout)) return -1;
      int l = ::send(s,buf,n,0);
      if((l == -1) && (errno != EINTR)) return -1;
      buf+=l; n-=l;
    };
    return size;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::HTTPSClientConnectorGSSAPI::eofread ( void  ) [protected, virtual]

If network connection was closed.

Reimplemented from Arc::HTTPSClientConnector.

Definition at line 628 of file HTTPSClientConnector.cpp.

                                               {
    return read_eof_flag;
  }
bool Arc::HTTPSClientConnectorGSSAPI::eofwrite ( void  ) [protected, virtual]

If there is pending buffer set by write()

Reimplemented from Arc::HTTPSClientConnector.

Definition at line 632 of file HTTPSClientConnector.cpp.

                                                {
    return (write_buf == NULL);
  }
bool Arc::HTTPSClientConnectorGSSAPI::read ( char *  buf = NULL,
unsigned int *  size = NULL 
) [protected, virtual]

Set buffer for reading data.

Reimplemented from Arc::HTTPSClientConnector.

Definition at line 545 of file HTTPSClientConnector.cpp.

                                                                    {
    if(s == -1) return false;
    read_size=size?*size:0;
    read_size_result=size;
    if(size) *size=0;
    read_buf=buf;
    return true;
  }
int Arc::HTTPSClientConnectorGSSAPI::read_SSL_token ( void **  val,
int  timeout 
) [private]

Definition at line 689 of file HTTPSClientConnector.cpp.

                                                                       {
    unsigned char header[5]; // SSL V3 header
    (*val)=NULL;
    int l = do_read((char*)header,sizeof(header),timeout);
    if(l == 0) return 0;
    if(l < 0) return -1;
    if(header[0] == (unsigned char)0x80) {
      /* SSL V2 - 2 byte header */
      l=((unsigned int)(header[1]))-3;
    } else if((header[0] >= 20) &&
              (header[0] <= 26) &&
              (header[1] == 3) &&
              (header[2] == 0 || header[2] == 1)) {
           /* SSL V3 */
      l=(((unsigned int)(header[3])) << 8) | ((unsigned int)(header[4]));
    } else {
      logger.msg(ERROR, "Urecognized SSL token received");
      return -1;
    };
    unsigned char* data = (unsigned char*)malloc(l+5);
    if(data == NULL) return -1;
    memcpy(data,header,5);
    if(l) {
      int ll = do_read((char*)(data+5),l,timeout);
      if(ll <= 0) {
        free(data);
        return -1;
      };
    };
    (*val)=data;
    return (l+5);
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::HTTPSClientConnectorGSSAPI::transfer ( bool &  read,
bool &  write,
int  timeout 
) [protected, virtual]

Transfer data set by read() and write(). Reset set buffers if operation complete.

Reimplemented from Arc::HTTPSClientConnector.

Definition at line 561 of file HTTPSClientConnector.cpp.

                                                                              {
    read=false; write=false;
    if(write_buf) {
      OM_uint32 major_status;
      OM_uint32 minor_status;
      gss_buffer_desc send_tok;
      gss_buffer_desc data_tok;
      int conf_state;
      data_tok.length=write_size;
      data_tok.value=(void*)write_buf;
      logger.msg(DEBUG, "*** Client request: %s", (char*)(data_tok.value));
      //for(globus_size_t n=0;n<data_tok.length;n++) odlog_(DEBUG)<<((char*)(data_tok.value))[n];
      //odlog_(DEBUG));
      major_status = gss_wrap(&minor_status,
                              context,
                              0,
                              GSS_C_QOP_DEFAULT,
                              &data_tok,
                              &conf_state,
                              &send_tok);
      if(major_status != GSS_S_COMPLETE) {
        logger.msg(ERROR, "Failed wrapping GSI token: %s", gss_error_string(major_status,minor_status));
        return false;
      };
      int to = timeout;
      int r = do_write((char*)(send_tok.value),send_tok.length,to);
      gss_release_buffer(&minor_status,&send_tok);
      write_buf=NULL; write_size=0; write=(r!=-1);
      return true;
    };
    if(read_buf) {
      gss_buffer_desc recv_tok;
      gss_buffer_desc data_tok = GSS_C_EMPTY_BUFFER;
      OM_uint32 major_status;
      OM_uint32 minor_status;
      int ll = read_SSL_token(&(recv_tok.value),timeout);
      if(ll == 0) { read_eof_flag=true; read=false; return true; };
      if(ll == -1) { read=false; return true; };
      recv_tok.length=ll;
      major_status = gss_unwrap(&minor_status,
                                context,
                                &recv_tok,
                                &data_tok,
                                NULL,
                                NULL);
      free(recv_tok.value);
      if(major_status != GSS_S_COMPLETE) {
        logger.msg(ERROR, "Failed unwrapping GSI token: %s", gss_error_string(major_status,minor_status));
        return false;
      };
      logger.msg(DEBUG, "*** Server response: %s", (char*)(data_tok.value));
      //for(globus_size_t n=0;n<data_tok.length;n++) odlog_(DEBUG)<<((char*)(data_tok.value))[n];
      //odlog_(DEBUG));
  
      if(data_tok.length > read_size) {
        logger.msg(ERROR, "Unwrapped data does not fit into buffer");
        return false;
      };
      memcpy(read_buf,data_tok.value,data_tok.length);
      if(read_size_result) (*read_size_result)=data_tok.length;
      gss_release_buffer(&minor_status,&data_tok);
      read_buf=NULL; read_size=0; read_size_result=NULL; read=true;
      return true;
    };
    return true;
  }

Here is the call graph for this function:

bool Arc::HTTPSClientConnectorGSSAPI::write ( const char *  buf = NULL,
unsigned int  size = 0 
) [protected, virtual]

Set data to be sent.

Reimplemented from Arc::HTTPSClientConnector.

Definition at line 554 of file HTTPSClientConnector.cpp.

                                                                          {
    if(s == -1) return false;
    write_size=size;
    write_buf=buf;
    return true;
  }

Member Data Documentation

Definition at line 150 of file HTTPSClient.h.

Definition at line 164 of file HTTPSClient.h.

Lock for mutex on connection (bug 1613)

Definition at line 86 of file HTTPSClient.h.

Definition at line 153 of file HTTPSClient.h.

gss_cred_id_t Arc::HTTPSClientConnectorGSSAPI::cred [private]

Definition at line 152 of file HTTPSClient.h.

Logger Arc::HTTPSClientConnector::logger [static, protected, inherited]

logger

Definition at line 105 of file HTTPSClient.h.

Definition at line 158 of file HTTPSClient.h.

Definition at line 161 of file HTTPSClient.h.

Definition at line 159 of file HTTPSClient.h.

Definition at line 160 of file HTTPSClient.h.

Definition at line 151 of file HTTPSClient.h.

Definition at line 154 of file HTTPSClient.h.

Definition at line 149 of file HTTPSClient.h.

Definition at line 162 of file HTTPSClient.h.

Definition at line 163 of file HTTPSClient.h.


The documentation for this class was generated from the following files: