Exemple #1
0
/**
 * Do the delegation
 * @param handle     The handle
 * @param url        The delegation endpoint
 * @param err_buffer Used to build the error string
 * @return NULL on failure, or an allocated string with the delegation ID
 */
static char *htext_delegate(htext_handle *handle, char *url, char *err_buffer)
{
  char                               *delegation_id = NULL;
  char                               *reqtxt  = NULL, *certtxt = NULL;
  char                               *keycert = NULL;
  struct soap                        *soap_get = NULL, *soap_put = NULL;
  struct tns__getNewProxyReqResponse  getNewProxyReqResponse;
  char                               *ucert = NULL, *ukey = NULL, *capath = NULL;
  int                                 lifetime;

  /* Get from the handle */
  ucert    = GETSTR(handle, HTEXTOP_USERCERTIFICATE);
  ukey     = GETSTR(handle, HTEXTOP_USERPRIVKEY);
  capath   = GETSTR(handle, HTEXTOP_CAPATH);
  lifetime = GETINT(handle, HTEXTOP_PROXYLIFE);

  /* Only one is needed if they are the same */
  if (ucert && !ukey) ukey  = ucert;
  if (!ucert && ukey) ucert = ukey;

  /* Cert and key need to be in the same file */
  if (strcmp(ucert, ukey) == 0) {
    keycert = strdup(ucert);
  }
  else {
    FILE *ifp, *ofp;
    int   fd;
    char  c;

    keycert = strdup("/tmp/.XXXXXX");

    fd = mkstemp(keycert);
    ofp = fdopen(fd, "w");

    ifp = fopen(ukey, "r");
    while ((c = fgetc(ifp)) != EOF) fputc(c, ofp);
    fclose(ifp);

    ifp = fopen(ukey, "r");
    while ((c = fgetc(ifp)) != EOF) fputc(c, ofp);
    fclose(ifp);

    fclose(ofp);
  }

  /* Initialize SSL */
  ERR_load_crypto_strings ();
  OpenSSL_add_all_algorithms();

  /* Request a new delegation ID */
  soap_get = soap_new();

  if (soap_ssl_client_context(soap_get, SOAP_SSL_DEFAULT, keycert, "",
                              NULL, capath, NULL) == 0) {
    soap_call_tns__getNewProxyReq(soap_get,
                                  url,
                                  "http://www.gridsite.org/namespaces/delegation-1",
                                  &getNewProxyReqResponse);

    if(soap_get->error == 0) {
      reqtxt        = getNewProxyReqResponse.getNewProxyReqReturn->proxyRequest;
      delegation_id = strdup(getNewProxyReqResponse.getNewProxyReqReturn->delegationID);

      /* Generate proxy */
      if (GRSTx509MakeProxyCert(&certtxt, stderr, reqtxt,
                                ucert, ukey, lifetime) == GRST_RET_OK) {
        /* Submit the proxy */
        soap_put = soap_new();

        if (soap_ssl_client_context(soap_put, SOAP_SSL_DEFAULT, keycert, "",
                              NULL, capath, NULL) == 0) {
            soap_call_tns__putProxy(soap_put,
                          url,
                          "http://www.gridsite.org/namespaces/delegation-1",
                          delegation_id, certtxt, NULL);
            if (soap_put->error) {
              /* Could not PUT */
#ifndef NO_SOAP_SPRINT
              soap_sprint_fault(soap_put, err_buffer, sizeof(err_buffer));
              htext_error(handle, err_buffer);
#else
              soap_print_fault(soap_put, stderr);
              handle->status = HTEXTS_FAILED;
#endif
            }
        }
        else { /* soap_put ssl error */
#ifndef NO_SOAP_SPRINT
          soap_sprint_fault(soap_put, err_buffer, sizeof(err_buffer));
          htext_error(handle, err_buffer);
#else
          soap_print_fault(soap_put, stderr);
          handle->status = HTEXTS_FAILED;
#endif
        }

        soap_free(soap_put);
      }
      else {
        htext_error(handle, "Could not generate the proxy");
      }
    }
    else { /* Could not get ID */
#ifndef NO_SOAP_SPRINT
      soap_sprint_fault(soap_get, err_buffer, sizeof(err_buffer));
      htext_error(handle, err_buffer);
#else
      soap_print_fault(soap_get, stderr);
      handle->status = HTEXTS_FAILED;
#endif
    }
  }
  else { /* soap_get ssl error */
#ifndef NO_SOAP_SPRINT
    soap_sprint_fault(soap_get, err_buffer, sizeof(err_buffer));
    htext_error(handle, err_buffer);
#else
    soap_print_fault(soap_put, stderr);
    handle->status = HTEXTS_FAILED;
#endif
  }

  /* Clean soap_get */
  soap_free(soap_get);
  free(keycert);
  free(certtxt);
  
  /* Return delegation ID */
  return delegation_id;
}
Exemple #2
0
int main(int argc, char *argv[])
{
  char  *delegation_id = "", *reqtxt, *certtxt, *valid = NULL, 
        *cert = NULL, *key = NULL, *capath = NULL, *keycert, timestr[81],
        *vomsdir = "/etc/grid-security/vomsdir",
        *executable, *keytxt, *proxychain, *ptr, *p;
  struct ns__putProxyResponse *unused = NULL;
  struct tm *finish_tm;
  int    option_index, c, noverify = 0, i, ret,
         method = HTPROXY_PUT, verbose = 0, fd, minutes;
  struct soap soap_get, soap_put;
  struct ns__getNewProxyReqResponse     getNewProxyReqResponse;
  struct ns__renewProxyReqResponse      renewProxyReqResponse;
  struct ns__destroyResponse            destroyResponse;
  struct ns__getTerminationTimeResponse getTerminationTimeResponse;
  FILE   *ifp, *ofp;
  STACK_OF(X509) *x509_certstack;
  X509   *x509_cert;
  BIO    *certmem;
  GRSTx509Chain *grst_chain = NULL;
  GRSTx509Cert  *grst_cert = NULL;
  long   ptrlen;
  struct stat statbuf;
  struct passwd *userpasswd; 
  struct option long_options[] = {      {"verbose",     0, 0, 'v'},
                                        {"cert",        1, 0, 0},
                                        {"key",         1, 0, 0},
                                        {"capath",      1, 0, 0},
                                        {"destroy",     0, 0, 0},
                                        {"time",        0, 0, 0},
                                        {"no-verify",   0, 0, 0},
                                        {"valid",       1, 0, 0},
                                        {"delegation-id",1, 0, 0},
                                        {"put",         0, 0, 0},
                                        {"renew",       0, 0, 0},
                                        {"unixtime",	0, 0, 0},
                                        {"make",	0, 0, 0},
                                        {"info",	0, 0, 0},
                                        {0, 0, 0, 0}  };

  if (argc == 1)
    {
      printsyntax(argv[0]);
      return 0;
    }

  while (1)
       {
         option_index = 0;
                                                                                
         c = getopt_long(argc, argv, "v", long_options, &option_index);

         if      (c == -1) break;
         else if (c == 0)
           {
             if      (option_index ==  1) cert            = optarg;
             else if (option_index ==  2) key             = optarg;
             else if (option_index ==  3) capath          = optarg;
             else if (option_index ==  4) method          = HTPROXY_DESTROY;
             else if (option_index ==  5) method          = HTPROXY_TIME;
             else if (option_index ==  6) noverify        = 1;
             else if (option_index ==  7) valid           = optarg;
             else if (option_index ==  8) delegation_id   = optarg;
             else if (option_index ==  9) method          = HTPROXY_PUT;
             else if (option_index == 10) method          = HTPROXY_RENEW;
             else if (option_index == 11) method          = HTPROXY_UNIXTIME;
             else if (option_index == 12) method          = HTPROXY_MAKE;
             else if (option_index == 13) method          = HTPROXY_INFO;
           }
         else if (c == 'v') 
                {
                  GRSTerrorLogFunc = htproxy_logfunc;
                  ++verbose;
                }
       }

  executable = rindex(argv[0], '/');
  if (executable != NULL) executable++;
  else                    executable = argv[0];
  
  if    (strcmp(executable, "htproxydestroy") == 0) method = HTPROXY_DESTROY;
  else if (strcmp(executable, "htproxyrenew") == 0) method = HTPROXY_RENEW;
  else if (strcmp(executable, "htproxytime") == 0)  method = HTPROXY_TIME;
  else if (strcmp(executable, "htproxyunixtime") == 0) 
                                                    method = HTPROXY_UNIXTIME;
  else if (strcmp(executable, "htproxymake") == 0)  method = HTPROXY_MAKE;
  else if (strcmp(executable, "htproxyinfo") == 0)  method = HTPROXY_INFO;

  if ((method != HTPROXY_MAKE) && 
      (method != HTPROXY_INFO) && (optind + 1 != argc))
    {
      fprintf(stderr, "Must specify a delegation service URL!\n");
      return 1;
    }

  if ((method == HTPROXY_RENEW) && (delegation_id[0] == '\0'))
    {
      fprintf(stderr, "Must give a Delegation ID when renewing\n");
      return 1;
    }
    
  if (valid == NULL) minutes = 60 * 12;
  else minutes = atoi(valid);
  
  if (verbose) fprintf(stderr, "Proxy valid for %d minutes\n", minutes);
 
  ERR_load_crypto_strings ();
  OpenSSL_add_all_algorithms();

  if      ((cert == NULL) && (key != NULL)) cert = key;
  else if ((cert != NULL) && (key == NULL)) key = cert;
  else if ((cert == NULL) && (key == NULL))
    {
      if (method != HTPROXY_MAKE) cert = getenv("X509_USER_PROXY");

      if (cert != NULL) key = cert;
      else
        {
          if (method != HTPROXY_MAKE) 
               asprintf(&(cert), "/tmp/x509up_u%d", geteuid());

          /* one fine day, we will check the proxy file for 
             expiry too to avoid suprises when we try to use it ... */

          if (stat(cert, &statbuf) == 0) key = cert;
          else if (method != HTPROXY_INFO)
            {
              cert = getenv("X509_USER_CERT");
              key  = getenv("X509_USER_KEY");
                                                                                
              userpasswd = getpwuid(geteuid());
                                                                                
              if ((cert == NULL) &&
                  (userpasswd != NULL) &&
                  (userpasswd->pw_dir != NULL))
                asprintf(&(cert), "%s/.globus/usercert.pem",
                                                    userpasswd->pw_dir);
                                                                                
              if ((key == NULL) &&
                  (userpasswd != NULL) &&
                  (userpasswd->pw_dir != NULL))
                asprintf(&(key), "%s/.globus/userkey.pem",
                                                    userpasswd->pw_dir);
                                                                                
            }
        }
    }
                                                                                
  if (capath == NULL) capath = getenv("X509_CERT_DIR");
  if (capath == NULL) capath = "/etc/grid-security/certificates";

  if (verbose) fprintf(stderr, "key=%s\ncert=%s\ncapath=%s\n",
                       key, cert, capath);

  if ((key != NULL) && (cert != NULL) &&
      (strcmp(key, cert) != 0)) /* we have to concatenate for gSOAP */
    {
      keycert = strdup("/tmp/.XXXXXX");
        
      fd = mkstemp(keycert);
      ofp = fdopen(fd, "w");
      if (!ofp)
      {
          fprintf(stderr, "Cannot open tmp file for the key\n");
          return 1;
      }
          
      ifp = fopen(key, "r");          
      {
          fprintf(stderr, "Cannot open the file with the key\n");
          return 1;
      }
      while ((c = fgetc(ifp)) != EOF) fputc(c, ofp);          
      fclose(ifp);
          
      ifp = fopen(cert, "r");          
      {
          fprintf(stderr, "Cannot open the file with the cert\n");
          return 1;
      }
      while ((c = fgetc(ifp)) != EOF) fputc(c, ofp);          
      fclose(ifp);
          
      fclose(ofp);       
          
      if (verbose) fprintf(stderr, "Created %s key/cert file\n", keycert);
    }
  else keycert = key;

  if ((method == HTPROXY_PUT) || (method == HTPROXY_RENEW))
    {
      if (verbose) 
        {
          fprintf(stderr, "Using SOAP delegation protocol\n");
          fprintf(stderr, "Delegation-ID: %s\n", delegation_id);
        }

      soap_init(&soap_get);
  
      if (soap_ssl_client_context(&soap_get,
                                  SOAP_SSL_DEFAULT,
                                  keycert, 
                                  "",
                                  NULL,
                                  capath,
                                  NULL))
        {
          soap_print_fault(&soap_get, stderr);
          return 1;
        } 

      if ((method == HTPROXY_RENEW) && (delegation_id[0] != '\0'))
        {
          if (verbose) fprintf(stderr, "Send renewProxyReq to service\n");

          soap_call_ns__renewProxyReq(&soap_get, 
                                argv[optind],	/* HTTPS url of service */
                                "http://www.gridsite.org/namespaces/delegation-1",
                                delegation_id, 
                                &renewProxyReqResponse);
      
          if (soap_get.error)
            {
              soap_print_fault(&soap_get, stderr);
              return 1;        
            }
       
          reqtxt = renewProxyReqResponse._renewProxyReqReturn;
        }
      else
        {
          if (verbose) fprintf(stderr, "Send getNewProxyReq to service\n");

          soap_call_ns__getNewProxyReq(&soap_get,
                            argv[optind],	/* HTTPS url of service */
                            "http://www.gridsite.org/namespaces/delegation-1",
                            &getNewProxyReqResponse);

          if (soap_get.error)
            {
              soap_print_fault(&soap_get, stderr);
              return 1;        
            }

          if (!getNewProxyReqResponse.getNewProxyReqReturn)
            {
              fprintf(stderr, "Empty response from getNewProxyReq\n");
              return 1;
            }

          reqtxt = getNewProxyReqResponse.getNewProxyReqReturn->proxyRequest;
          delegation_id = 
                   getNewProxyReqResponse.getNewProxyReqReturn->delegationID;
        }
 
      if (verbose) fprintf(stderr, "reqtxt:\n%s", reqtxt);
      
      if (GRSTx509MakeProxyCert(&certtxt, stderr, reqtxt, cert, key, minutes) 
          != GRST_RET_OK)
        {
          return 1;
        }

      soap_init(&soap_put);
  
      if (verbose) fprintf(stderr, "Send putProxy to service:\n%s\n", certtxt);

      if (soap_ssl_client_context(&soap_put,
                                  SOAP_SSL_DEFAULT,
                                  keycert, 
                                  "",
                                  NULL,
                                  capath,
                                  NULL))
        {
          soap_print_fault(&soap_put, stderr);
          return 1;
        } 

      soap_call_ns__putProxy(&soap_put, argv[optind],
                             "http://www.gridsite.org/namespaces/delegation-1",
                             delegation_id, 
                             certtxt, unused);      
      if (soap_put.error)
        {
          soap_print_fault(&soap_put, stderr);
          return 1;        
        }

      puts(delegation_id);

      return 0;
    }  
  else if (method == HTPROXY_DESTROY)
    {
      if (verbose) 
        {
          fprintf(stderr, "Using SOAP proxy destroy protocol\n");
          fprintf(stderr, "Delegation-ID: %s\n", delegation_id);
        }

      soap_init(&soap_put);
  
      if (verbose) fprintf(stderr, "Send destroy to service:\n");

      if (soap_ssl_client_context(&soap_put,
                                  SOAP_SSL_DEFAULT,
                                  keycert, 
                                  "",
                                  NULL,
                                  capath,
                                  NULL))
        {
          soap_print_fault(&soap_put, stderr);
          return 1;
        } 

      soap_call_ns__destroy(&soap_put, argv[optind],
                             "http://www.gridsite.org/namespaces/delegation-1",
                             delegation_id, 
                             &destroyResponse);
      if (soap_put.error)
        {
          soap_print_fault(&soap_put, stderr);
          return 1;        
        }

      return 0;
    }  
  else if ((method == HTPROXY_TIME) || (method == HTPROXY_UNIXTIME))
    {
      if (verbose) 
        {
          fprintf(stderr, "Using SOAP proxy get expiration time protocol\n");
          fprintf(stderr, "Delegation-ID: %s\n", delegation_id);
        }

      soap_init(&soap_put);
  
      if (verbose) fprintf(stderr, "Send get time to service:\n");

      if (soap_ssl_client_context(&soap_put,
                                  SOAP_SSL_DEFAULT,
                                  keycert, 
                                  "",
                                  NULL,
                                  capath,
                                  NULL))
        {
          soap_print_fault(&soap_put, stderr);
          return 1;
        } 

      soap_call_ns__getTerminationTime(&soap_put, argv[optind],
                             "http://www.gridsite.org/namespaces/delegation-1",
                             delegation_id, 
                             &getTerminationTimeResponse);
      if (soap_put.error)
        {
          soap_print_fault(&soap_put, stderr);
          return 1;        
        }


      if (method == HTPROXY_UNIXTIME)
       printf("%ld\n", getTerminationTimeResponse._getTerminationTimeReturn);
      else
        {
          finish_tm = 
           localtime(&(getTerminationTimeResponse._getTerminationTimeReturn));

          strftime(timestr, sizeof(timestr),
                       "%a %b %e %H:%M:%S %Z %Y\n", finish_tm);
                       
          fputs(timestr, stdout);
        }
        
      return 0;
    }  
  else if (method == HTPROXY_MAKE)
#ifdef HT_LEAK_TEST
    {
    int ii;
    FILE *ffpp;
    char lineline[80];
    for (ii=0; ii < 1000; ++ii)
#endif
    {
      if (GRSTx509CreateProxyRequestKS(&reqtxt, &keytxt, NULL, 0) != GRST_RET_OK)
        {
          fprintf(stderr, "Failed to create internal proxy cert request\n");
          return 1;
        }
      
#ifdef HT_LEAK_TEST      
     ffpp = fopen("/proc/self/statm", "r");
     fgets(lineline, sizeof(lineline), ffpp);
     fprintf(stderr, "%d a %s", ii, lineline);
     fclose(ffpp);
#endif
      if (GRSTx509MakeProxyCert(&proxychain, NULL, reqtxt, cert, key, minutes)
            != GRST_RET_OK)
        {
          fprintf(stderr, "Failed to sign internal proxy cert request\n");
          return 2;
        }
        
#ifdef HT_LEAK_TEST      
     ffpp = fopen("/proc/self/statm", "r");
     fgets(lineline, sizeof(lineline), ffpp);
     fprintf(stderr, "%d b %s", ii, lineline);
     fclose(ffpp);
#endif

      /* convert back to cert stack so can output in the right order */
      if (GRSTx509StringToChain(&x509_certstack, proxychain) != GRST_RET_OK)
        {
          fprintf(stderr, "Failed to convert internal proxy chain\n");
          return 3;
        }
        
#ifdef HT_LEAK_TEST      
     ffpp = fopen("/proc/self/statm", "r");
     fgets(lineline, sizeof(lineline), ffpp);
     fprintf(stderr, "%d c %s", ii, lineline);
     fclose(ffpp);
#endif

      /* just the proxy certificate we have created */
      if ((x509_cert = sk_X509_value(x509_certstack, 0)))
        {
          certmem = BIO_new(BIO_s_mem());
          if (PEM_write_bio_X509(certmem, x509_cert) == 1)
            {
              ptrlen = BIO_get_mem_data(certmem, &ptr);
              fwrite(ptr, 1, ptrlen, stdout);
            }
                                                          
          BIO_free(certmem);
        }
                                                                    
#ifdef HT_LEAK_TEST      
     ffpp = fopen("/proc/self/statm", "r");
     fgets(lineline, sizeof(lineline), ffpp);
     fprintf(stderr, "%d d %s", ii, lineline);
     fclose(ffpp);
#endif
      /* then the private key */ 
      fputs(keytxt, stdout);
      
      /* and only now the rest of the certificates */
      for (i=1; i <= sk_X509_num(x509_certstack) - 1; ++i)
        /* loop through the proxy chain starting at 2nd most recent proxy */
         {
           if ((x509_cert = sk_X509_value(x509_certstack, i)))
             {
               certmem = BIO_new(BIO_s_mem());
               if (PEM_write_bio_X509(certmem, x509_cert) == 1)
                 {
                   ptrlen = BIO_get_mem_data(certmem, &ptr);
                   fwrite(ptr, 1, ptrlen, stdout);
                 }

               BIO_free(certmem);
             }
         }

 
#ifdef HT_LEAK_TEST      
     ffpp = fopen("/proc/self/statm", "r");
     fgets(lineline, sizeof(lineline), ffpp);
     fprintf(stderr, "%d e %s", ii, lineline);
     fclose(ffpp);
#endif
      free(proxychain);
      free(keytxt);
      free(reqtxt);
      sk_X509_free(x509_certstack);
      
#ifdef HT_LEAK_TEST      
     ffpp = fopen("/proc/self/statm", "r");
     fgets(lineline, sizeof(lineline), ffpp);
     fprintf(stderr, "%d f %s", ii, lineline);
     fclose(ffpp);
    }
#endif
      return 0;
    }
  else if (method == HTPROXY_INFO)
    {
      if (cert != NULL) 
        {
          if (verbose) fprintf(stderr, "Getting proxy info from %s\n", cert);
    
          ifp = fopen(cert, "r");
          if (ifp == NULL)
            {
              fprintf(stderr, "Failed to open proxy file\n");
              return 2;              
            }
        }
      else  
        {
          if (verbose) fprintf(stderr, "Getting proxy info from stdin\n");
          ifp = stdin;
        }
      
      ptrlen = 4096;
      ptr = malloc(ptrlen);
      i = 0;
      
      while ((c = fgetc(ifp)) != EOF)
           {
             ptr[i] = c;
             ++i;
             
             if (i >= ptrlen) 
               {
                 ptrlen += 4096;
                 ptr = realloc(ptr, ptrlen);
               }
           }
           
      ptr[i] = '\0';
      if (cert != NULL) fclose(ifp);
      
      if ((GRSTx509StringToChain(&x509_certstack, ptr) != GRST_RET_OK) ||
          (x509_certstack == NULL))
        {
          fprintf(stderr, "Failed to parse proxy file for certificate chain\n");
          free(ptr);
          return 2;
        }

      free(ptr);

      if (verbose) fprintf(stderr, "Parsing certificate chain\n");
      
      ret = GRSTx509ChainLoadCheck(&grst_chain, x509_certstack, NULL,  
                                   capath, vomsdir);
      
      if ((ret != GRST_RET_OK) || 
          (grst_chain == NULL) || (grst_chain->firstcert == NULL))
        {
          fprintf(stderr, "Failed parsing certificate chain\n");
          return 3;
        }
      
      grst_cert = grst_chain->firstcert;

      for (i=0; grst_cert != NULL; grst_cert = grst_cert->next, ++i)
         {
           if      (grst_cert->type == GRST_CERT_TYPE_CA)    p = "(CA) ";
           else if (grst_cert->type == GRST_CERT_TYPE_EEC)   p = "(EEC) ";
           else if (grst_cert->type == GRST_CERT_TYPE_PROXY) p = "(PC) ";
           else if (grst_cert->type == GRST_CERT_TYPE_VOMS)  p = "(AC) ";
           else p = "";
                              
           printf("%d %s%s\n", i, p,
                  (grst_cert->type == GRST_CERT_TYPE_VOMS) 
                    ? grst_cert->value : grst_cert->dn);
 
           printf(" Status     : %d ( %s%s%s%s%s%s)\n", grst_cert->errors,
                 (grst_cert->errors == 0) ? "OK " : "",
                 (grst_cert->errors & GRST_CERT_BAD_FORMAT) ? "BAD_FORMAT ":"",
                 (grst_cert->errors & GRST_CERT_BAD_CHAIN)  ? "BAD_CHAIN ":"",
                 (grst_cert->errors & GRST_CERT_BAD_SIG)    ? "BAD_SIG ":"",
                 (grst_cert->errors & GRST_CERT_BAD_TIME)   ? "BAD_TIME ":"",
                 (grst_cert->errors & GRST_CERT_BAD_OCSP)   ? "BAD_OCSP ":"");

           printf(" Start      : %s",   ctime(&(grst_cert->notbefore)));
           printf(" Finish     : %s",   ctime(&(grst_cert->notafter)));
           printf(" Delegation : %d\n", grst_cert->delegation);

           if (grst_cert->type == GRST_CERT_TYPE_VOMS)
             {
               printf(" User DN    : %s\n", grst_cert->dn);
               printf(" VOMS DN    : %s\n\n", grst_cert->issuer);
             }
           else
             {
               printf(" Serial     : %s\n", grst_cert->serial);
               printf(" Issuer     : %s\n\n", grst_cert->issuer);              
             }
         }
      
      GRSTx509ChainFree(grst_chain);
    }
  /* weirdness */
}
Exemple #3
0
int glite_delegation_delegate(glite_delegation_ctx *ctx, 
    const char *delegationID, int expiration, int force)
{
    char *sdelegationID = "", *localproxy, *certreq, *certtxt, *scerttxt;
    
    struct delegation__getProxyReqResponse get_resp;
    struct delegation__renewProxyReqResponse renew_resp;
    struct delegation__getTerminationTimeResponse term_resp;
    struct delegation__putProxyResponse put_resp;
    time_t term_time;
    int ret;

    if(!ctx)
        return -1;
    
    if (NULL == (localproxy = getenv("X509_USER_PROXY")))
    {
        if (GLOBUS_GSI_SYSCONFIG_GET_PROXY_FILENAME(&localproxy,
            GLOBUS_PROXY_FILE_INPUT))
        {
                glite_delegation_set_error(ctx, "glite_delegation_dowork: unable to get"
                " user proxy filename!");
            return -1;
        }
    }

    /* error is already set */
    if (!ctx->soap) 
        return -1;

    if (delegationID)
    {
        sdelegationID = soap_strdup(ctx->soap, delegationID);
        if (!sdelegationID)
        {
            glite_delegation_set_error(ctx, "glite_delegation_dowork: soap_strdup()"
                           " of delegationID failed!");
            return -1;
        }
    }

    /* using certreq as a marker */
    certreq = NULL;
    if (force) 
    {
        /* force the renewal of the proxy */
        ret = soap_call_delegation__renewProxyReq(ctx->soap, ctx->endpoint, NULL,
                                                  sdelegationID, &renew_resp);
        if (SOAP_OK != ret)
        {
            _fault_to_error(ctx, __func__);
            return -1;
        }
        certreq = renew_resp._renewProxyReqReturn;
    }

    /* if it was forced and failed, or if it was not forced at all */
    if (NULL == certreq) 
    {
        /* there was no proxy, or not forcing -- the normal path */
        ret = soap_call_delegation__getProxyReq(ctx->soap, ctx->endpoint, NULL,
                                                     sdelegationID, &get_resp);
        if (SOAP_OK != ret)
        {
            _fault_to_error(ctx, __func__);
            return -1;
        }
        certreq = get_resp._getProxyReqReturn;
    }

    /* generating a certificate from the request */
    ret = GRSTx509MakeProxyCert(&certtxt, stderr, certreq, 
        localproxy, localproxy, expiration);
    if (ret != GRST_RET_OK)
    {
        glite_delegation_set_error(ctx, "glite_delegation_delegate: "
                                   "GRSTx509MakeProxyCert call failed");
        return -1;
    }

    scerttxt = soap_strdup(ctx->soap, certtxt);
    if (!scerttxt)
    {
        glite_delegation_set_error(ctx, "glite_delegation_delegate: soap_strdup()"
                                   " of delegationID failed!");
        return -1;
    }

    if (SOAP_OK != soap_call_delegation__putProxy(ctx->soap, ctx->endpoint, NULL,
                                                  sdelegationID, scerttxt, &put_resp))
    {
            _fault_to_error(ctx, __func__);
            return -1;
    }

    return 0;
}