⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 certauth_extensions.c

📁 代理服务器源代码 供大家学习使用,希望大家喜欢
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * CA extension implementation file * */#include "myproxy_common.h"#define BUF_SIZE 16384#ifndef MIN#define MIN(x,y) ((x) < (y) ? (x) : (y))#endif#define SECONDS_PER_HOUR (60 * 60)static int read_cert_request(GSI_SOCKET *self,		  unsigned char **buffer,		  size_t *length) {  int             return_value = 1;  unsigned char * input_buffer = NULL;  size_t          input_buffer_length;  if (self == NULL) {    verror_put_string("read_cert_request(): Socket is null");    goto error;  }  if (GSI_SOCKET_read_token(self, &input_buffer,			    &input_buffer_length) == GSI_SOCKET_ERROR) {    verror_put_string("read_cert_request(): Read from socket failed");    goto error;  }  *buffer = input_buffer;  *length = input_buffer_length;  return_value = 0; error:  if ( return_value ) {    if ( input_buffer != NULL ) {      myproxy_debug("freeing buffer");      free(input_buffer);      input_buffer = NULL;    }  }  return return_value;}static int send_certificate(GSI_SOCKET *self,		 unsigned char *buffer,		 size_t length) {  if (GSI_SOCKET_write_buffer(self, (const char *)buffer, 			      length) == GSI_SOCKET_ERROR) {    verror_put_string("Error writing certificate to client!");    return 1;  }  return 0;}static void add_key_value( char * key, char * value, char buffer[] ) {  strcat( buffer, key );  strcat( buffer, "=" );  if ( value == NULL ) {    strcat( buffer, "NULL" );  } else {    strcat( buffer, value );  }  strcat( buffer, "\n" );}static int external_callout( X509_REQ                 *request, 		  X509                     **cert,		  myproxy_request_t        *client_request,		  myproxy_server_context_t *server_context) {  int return_value = 1;  char buffer[BUF_SIZE];  char intbuf[128];  pid_t pid;  int p0[2], p1[2], p2[2];  int status;  FILE * pipestream = NULL;  X509 * certificate = NULL;  memset(buffer, '\0', BUF_SIZE);  memset(intbuf, '\0', 128);  myproxy_debug("callout using: %s", 		server_context->certificate_issuer_program);  /* create pipe */  if ( pipe(p0) < 0 || pipe(p1) < 0 || pipe(p2) < 0 ) {    verror_put_string("pipe() failed");    verror_put_errno(errno);    goto error;  }  /* create child */  if ( (pid = fork()) < 0 ) {    verror_put_string("fork() failed");    verror_put_errno(errno);    goto error;  }  /* attach pipes to appropriate streams in child and exec */  if (pid == 0) {    close(p0[1]); close(p1[0]); close(p2[0]);    dup2(p0[0], 0); /*in*/    dup2(p1[1], 1); /*out*/    dup2(p2[1], 2); /*error*/    execl(server_context->certificate_issuer_program, 	  server_context->certificate_issuer_program, NULL);    perror("exec");    fprintf(stderr, "failed to run %s: %s\n",	    server_context->certificate_issuer_program, strerror(errno));    exit(1);  }  /* close unused pipes on the parent side */  close(p0[0]);  close(p1[1]);  close(p2[1]);  /* writing to program */  pipestream = fdopen( p0[1], "w" );  if ( pipestream == NULL ) {    verror_put_string("File stream to stdin pipe creation problem.");    return 1;  }  add_key_value( "username", client_request->username, buffer );  add_key_value( "passphrase", client_request->passphrase, buffer );  sprintf( intbuf, "%d", client_request->proxy_lifetime );  add_key_value( "proxy_lifetime", (char*)intbuf, buffer );  memset(intbuf, '\0', 128);  add_key_value( "retrievers", client_request->retrievers, buffer );  add_key_value( "renewers", client_request->renewers, buffer );  add_key_value( "credname", client_request->credname, buffer );  add_key_value( "creddesc", client_request->creddesc, buffer );  add_key_value( "authzcreds", client_request->authzcreds, buffer );  add_key_value( "keyretrieve", client_request->keyretrieve, buffer );  add_key_value( "trusted_retrievers", client_request->trusted_retrievers,		 buffer );  sprintf( intbuf, "%d", server_context->max_cert_lifetime );  add_key_value( "max_cert_lifetime", (char*)intbuf, buffer );  memset(intbuf, '\0', 128);  fprintf( pipestream, "%s\n", buffer );  PEM_write_X509_REQ( pipestream, request );  fflush( pipestream );  fclose( pipestream );  close(p0[1]);  /* wait for program to exit */  if( waitpid(pid, &status, 0) == -1 ) {    verror_put_string("waitpid() failed for external callout child");    verror_put_errno(errno);    goto error;  }  /* check status and read appropriate content */  /* if exit != 0 - read and log message from program stderr */  if ( status != 0 ) {    verror_put_string("external process exited abnormally\n");    memset(buffer, '\0', BUF_SIZE);    if ( read( p2[0], buffer, BUF_SIZE ) > 0 ) {      verror_put_string(buffer);    } else {      verror_put_string("did not recieve an error string from callout");    }    goto error;  }  /* retrieve the certificate */  pipestream = fdopen( p1[0], "r" );  if ( pipestream == NULL ) {    verror_put_string("File stream to stdout pipe creation problem.");    goto error;  }  certificate = PEM_read_X509( pipestream, NULL, NULL, NULL );  if (certificate == NULL) {    verror_put_string("Error reading certificate from external program.");    goto error;  } else {    myproxy_debug("Recieved certificate from external callout.");  }  fclose( pipestream );  close(p1[0]);  close(p2[0]);  /* good to go */  *cert = certificate;  return_value = 0; error:  memset(buffer, '\0', BUF_SIZE);  memset(intbuf, '\0', 128);  return return_value;}static int tokenize_to_x509_name( char * dn, X509_NAME * name ) {  int return_value = 0;  char * tmp;  char * tok;  char * tmpTok = NULL;  char * subtok;  char * toksplit;  int i;  myproxy_debug( "tokenizing: %s", dn );  tmp = strdup(dn);  tok = strtok( tmp, "/" );  while ( tok != NULL ) {    subtok = strchr( tok, '=' );    toksplit = subtok;    subtok++;    *toksplit = '\0';    /* if short prefixes are being used, they need to be capped before       feeding to the add entry function. tok must be strdup()ed because       messing with the strtok() buffer is bad. */    tmpTok = strdup( tok );    if ( strlen( tmpTok ) < 3 ) {      i = 0;      while( i < strlen( tmpTok ) ) {	tmpTok[i] = toupper( tmpTok[i] );	i = i + 1;      }    }    myproxy_debug( "adding: %s = %s", tmpTok, subtok );    if (!X509_NAME_add_entry_by_txt( name, tmpTok, MBSTRING_ASC, 				     (unsigned char *) subtok, -1, -1, 0 )) {      verror_put_string("Error adding %s = %s to x509 name", tmpTok, subtok );      verror_put_string("Invalid field name");      return_value = 1;      goto end;    }    subtok = NULL;    toksplit = NULL;    free( tmpTok );    tmpTok = NULL;    tok = strtok( NULL, "/" );  } end:  free(tmp);  return return_value;}/* Use fcntl() for POSIX file locking. Lock is released when file is closed. */static intlock_file(int fd){    struct flock fl;    fl.l_type = F_WRLCK;    fl.l_whence = SEEK_SET;    fl.l_start = 0;    fl.l_len = 0;    while( fcntl( fd, F_SETLKW, &fl ) < 0 )    {	if ( errno != EINTR )	{	    return -1;	}    }    return 0;}/* * serial number handling liberally borrowed from KCA with the addition * of file locking */static int assign_serial_number( X509 *cert, 		      myproxy_server_context_t *server_context ) {  int increment  = 1;  int retval = 1;  long serialset;  BIGNUM       * serial = NULL;  ASN1_INTEGER * current = NULL, * next = NULL;  char buf[1024];  char *serialfile = NULL;  /* all the io variables */  BIO   * serialbio = NULL;  int     fd;  FILE  * serialstream = NULL;  myproxy_debug("Assigning serial number");  serial  = BN_new();  current = ASN1_INTEGER_new();  if ( (serial ==NULL) || (current==NULL) ) {    verror_put_string("Bignum/asn1 INT init failure\n");    goto error;  }  if (server_context->certificate_serialfile) {      serialfile = server_context->certificate_serialfile;  } else {      const char *sdir;      sdir = myproxy_get_storage_dir();      if (sdir == NULL) {	  goto error;      }      serialfile = malloc(strlen(sdir)+strlen("/serial")+1);      sprintf(serialfile, "%s/serial", sdir);  }  /* open(), lock, open stream and create BIO */  fd = open( serialfile, O_RDWR|O_CREAT, 0600 );  if ( fd == -1 ) {    verror_put_string("Call to open() failed on %s\n", serialfile);    goto error;  }  if ( lock_file(fd) == -1 ) {    verror_put_string("Failed to get lock on file descriptor\n");    verror_put_errno(errno);    goto error;  }  serialstream = fdopen( fd, "w+" );  if ( serialstream == NULL ) {    verror_put_string("Unable to open file stream\n");    goto error;  }  /* check if file is empty, and if so, initialize with 1 */  if (fseek(serialstream, 0L, SEEK_END) < 0) {    verror_put_string("Unable to seek file stream\n");    goto error;  }  serialset = ftell(serialstream);  if (serialset) rewind(serialstream);  serialbio = BIO_new_fp( serialstream, BIO_CLOSE );  if ( serialbio == NULL ) {    verror_put_string("BIO_new_fp failure.\n");    goto error;  }  if (serialset) {      if (!a2i_ASN1_INTEGER(serialbio, current, buf, sizeof(buf))) {	  verror_put_string("Asn1 int read/conversion error\n");	  goto error;      } else {	  myproxy_debug("Loaded serial number %s from %s", buf, serialfile);      }  } else {      ASN1_INTEGER_set(current, 1);  }  serial = BN_bin2bn( current->data, current->length, serial );  if ( serial == NULL ) {    verror_put_string("Error converting to bignum\n");    goto error;  }  if (!BN_add_word(serial, increment)) {    verror_put_string("Error incrementing serial number\n");    goto error;  }  if (!(next = BN_to_ASN1_INTEGER(serial, NULL))) {    verror_put_string("Error converting new serial to ASN1\n");    goto error;  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -