int DestroyMutexes ( void ) {

  /* Get the global shared memory mutex */
  XProcLock();

  /* Give up the global shared memory mutex */

  XProcUnLock();

  return TRUE;

}
Beispiel #2
0
int DestroyMutexes ( void ) {

  /* Get the global shared memory mutex */
  XProcLock();


  #if TEST_COND_VARS
    if ( ! DestroyConditionVariables() ) {
      return FALSE;
    }
  #endif /* TEST_COND_VARS */


#ifdef FIXME
    //  SAB  FIXME... This is really useless as we don't use the 
    //  per process mutexes on the shared memory... thank goodness, since
    //  this would have complicated the linux port as it does not support
    //  Process  shared mutexes
    //  of course when we want to use these mutexes we need to figure out
    //  how to handle it in linux... 
  /* Destroy the per-process mutexes */
  for ( i = 0; i < NUMBER_PROCESSES_ALLOWED; i++ ) {
    /* Should I get and release the per-process mutexes here? */

    /* 
       No.  The only way this'll get called is if no processes are currently attached to the slotmgr
       So, in theory, noone should be holding a mutex - if they are, it's in error
     */
    /* FIXME: Should make sure that they were successfully created before destroying them */

#ifdef PKCS64
    msem_remove(&(shmp->proc_table[i].proc_mutex));
#else
    pthread_mutex_destroy( &(shmp->proc_table[i].proc_mutex) );
#endif

  }
#endif

  /* Give up the global shared memory mutex */
  /* (we have to release it before we destroy it, otherwise the behavior's undefined) */


  XProcUnLock();

  return TRUE;

}
BOOL CheckForGarbage ( Slot_Mgr_Shr_t *MemPtr ) {

  int               SlotIndex;
  int               ProcIndex;
  int               Err;
  BOOL              ValidPid;

  ASSERT( MemPtr != NULL_PTR );
  #ifdef DEV
    DbgLog(DL5, "Thread %d is checking for garbage", pthread_self());
  #endif /* DEV */


  #ifdef DEV
    DbgLog (DL5, "Garbage collection attempting global shared memory lock");
  #endif /* DEV */

  /* Grab the global Shared mem mutex since we might modify global_session_count */

    Err = XProcLock();
  if ( Err != TRUE ) {
    DbgLog (DL0, "Garbage collection: Locking attempt for global shmem mutex returned %s", SysConst(Err) );
    return FALSE;
  }

  #ifdef DEV
  DbgLog ( DL5, "Garbage collection: Got global shared memory lock");
  #endif /* DEV */


  for ( ProcIndex = 0; ProcIndex < NUMBER_PROCESSES_ALLOWED; ProcIndex++ ) {

    Slot_Mgr_Proc_t_64 *pProc = &(MemPtr->proc_table[ProcIndex]);

    ASSERT(pProc != NULL_PTR);

    if ( ! (pProc->inuse) ) {
      continue;
    }

    ValidPid = ( (IsValidProcessEntry ( pProc->proc_id, pProc->reg_time )) && (pProc->proc_id != 0) );


    if ( ( pProc->inuse ) && (! ValidPid ) ) {

      #ifdef DEV
        DbgLog(DL1, "Garbage collection routine found bad entry for pid %d (Index: %d); removing from table", pProc->proc_id, ProcIndex );
      #endif /* DEV */

      /*                         */
      /* Clean up session counts */
      /*                         */
      for ( SlotIndex = 0; SlotIndex < NUMBER_SLOTS_MANAGED; SlotIndex++ ) {

	unsigned int *pGlobalSessions =
		      &(MemPtr->slot_global_sessions[SlotIndex]);
	unsigned int *pProcSessions = &(pProc->slot_session_count[SlotIndex]);

	if ( *pProcSessions > 0 ) {

  	  #ifdef DEV
	    DbgLog ( DL2, "GC: Invalid pid (%d) is holding %d sessions open on slot %d.  Global session count for this slot is %d", pProc->proc_id, *pProcSessions, SlotIndex, *pGlobalSessions );
          #endif /* DEV */

	  if ( *pProcSessions > *pGlobalSessions ) {
	    #ifdef DEV
	      WarnLog ( "Garbage Collection: Illegal values in table for defunct process");
	      DbgLog  ( DL0, "Garbage collection: A process ( Index: %d, pid: %d ) showed %d sessions open on slot %s, but the global count for this slot is only %d",
			ProcIndex, pProc->proc_id, *pProcSessions, SlotIndex, *pGlobalSessions );
	    #endif /* DEV */
	    *pGlobalSessions = 0;
	  } else {
	    *pGlobalSessions -= *pProcSessions;
	  }

	  *pProcSessions = 0;

	} /* end if *pProcSessions */

      } /* end for SlotIndex */


      /*                                      */
      /* NULL out everything except the mutex */
      /*                                      */

      memset( &(pProc->inuse),              '\0', sizeof(pProc->inuse) );
      memset( &(pProc->proc_id),            '\0', sizeof(pProc->proc_id) );
      memset( &(pProc->slotmap),            '\0', sizeof(pProc->slotmap) );
      memset( &(pProc->blocking),           '\0', sizeof(pProc->blocking ));
      memset( &(pProc->error),              '\0', sizeof(pProc->error) );
      memset( &(pProc->slot_session_count), '\0', sizeof(pProc->slot_session_count) );
      memset( &(pProc->reg_time),           '\0', sizeof(pProc->reg_time) );

    } /* end if inuse && ValidPid */

  } /* end for ProcIndex */

  XProcUnLock();
  DbgLog ( DL5, "Garbage collection: Released global shared memory lock");

  return TRUE;

}
Beispiel #4
0
CK_RV
ST_Initialize(void *FunctionList,
	CK_SLOT_ID SlotNumber,
	unsigned char *Correlator)
{
	CK_RV  rc = CKR_OK;
	struct ST_FCN_LIST *flist = (struct ST_FCN_LIST *)FunctionList;
	TSS_HCONTEXT hContext = 0;

	stlogterm();
	stloginit();

	if (st_Initialized() == TRUE) {
		return (CKR_OK);
	}
	// assume that the upper API prevents multiple calls of initialize
	// since that only happens on C_Initialize and that is the
	// resonsibility of the upper layer..
	initialized = FALSE;

	// check for other completing this before creating mutexes...
	// make sure that the same process tried to to the init...
	// thread issues should be caught up above...
	if (st_Initialized() == TRUE) {
		goto done;
	}

	Fork_Initializer();

	(void) pthread_mutex_init(&pkcs_mutex, NULL);
	(void) pthread_mutex_init(&obj_list_mutex, NULL);
	(void) pthread_rwlock_init(&obj_list_rw_mutex, NULL);

	(void) pthread_mutex_init(&sess_list_mutex, NULL);
	(void) pthread_mutex_init(&login_mutex, NULL);

	if (st_Initialized() == FALSE) {
		if ((rc = attach_shm()) != CKR_OK)
			goto done;

		nv_token_data = &global_shm->nv_token_data;

		initialized = TRUE;
		initedpid = getpid();
		SC_SetFunctionList();

		if (flist != NULL)
			(*flist) = function_list;

		/* Always call the token_specific_init function.... */
		rc = token_specific.t_init((char *)Correlator, SlotNumber,
		    &hContext);
		if (rc != 0) {
			/*
			 * The token could not be initialized, return OK, but
			 * present no slots.
			 */
			rc = CKR_OK;
			goto done;
		} else {
			/* Mark the token as available */
			global_shm->token_available = TRUE;
		}
	}

	rc = load_token_data(hContext, nv_token_data);

	if (rc != CKR_OK) {
		goto done;
	}

	rc = load_public_token_objects();
	if (rc != CKR_OK)
		goto done;

	(void) XProcLock(xproclock);
	global_shm->publ_loaded = TRUE;
	(void) XProcUnLock(xproclock);

	init_slot_info(nv_token_data);

done:
	if (hContext)
		Tspi_Context_Close(hContext);
	return (rc);
}
int main ( int argc, char *argv[], char *envp[]) {
   int ret;

   /**********************************/
   /* Read in command-line arguments */
   /**********************************/

   /* FIXME: Argument for daemonizing or not */
   /* FIXME: Argument for debug level */
   /* FIXME: Arguments affecting the log files, whether to use syslog, etc. (Read conf file?) */


   /* Report our debug level */
   if ( GetDebugLevel() > DEBUG_NONE) {

     DbgLog(GetDebugLevel(), "Starting with debugging messages logged at level %d (%d = No messages; %d = few; %d = more, etc.)", 
	    GetDebugLevel(), DEBUG_NONE, DEBUG_LEVEL0, DEBUG_LEVEL1);

   }


   /* Save our startup directory */
   SaveStartupDirectory( argv[0]  );

   ret = load_and_parse(OCK_CONFIG);
   if (ret != 0) {
      ErrLog("Failed to read config file.\n");
      return 1;
   } else
      DbgLog (DL0, "Parse config file succeeded.\n");

   /* Allocate and Attach the shared memory region */
   if ( ! CreateSharedMemory() ) {
     /* CreateSharedMemory() does it's own error logging */
     return 1;
   }

   DbgLog(DL0,"SHMID %d  token %#X \n", shmid, tok);

   /* Now that we've created the shared memory segment, we attach to it */
   if ( ! AttachToSharedMemory() ) {
     /* AttachToSharedMemory() does it's own error logging */
     DestroySharedMemory();
     return 2;
   }

   /* Initialize the global shared memory mutex (and the attribute used to create the per-process mutexes */
   if ( ! InitializeMutexes() ) {
     DetachFromSharedMemory();
     DestroySharedMemory();
     return 3;
   }

   /* Get the global shared memory mutex */

   XProcLock();

   /* Populate the Shared Memory Region */
   if ( ! InitSharedMemory(shmp) ) {

      XProcUnLock();

     DetachFromSharedMemory();
     DestroySharedMemory();
     return 4;
   }
   
   /* Release the global shared memory mutex */
   XProcUnLock();

   if ((socketfd = CreateListenerSocket()) < 0) {
      DestroyMutexes();
      DetachFromSharedMemory();
      DestroySharedMemory();
      return 5;
   }

   if (!InitSocketData(&socketData)) {
      DetachSocketListener(socketfd);
      DestroyMutexes();
      DetachFromSharedMemory();
      DestroySharedMemory();
      return 6;
   }

   /*
    *  Become a Daemon, if called for
    */
   if ( Daemon ) {
        pid_t  pid;
        if ( (pid = fork()) < 0 ){
          DetachSocketListener(socketfd);
          DestroyMutexes();
          DetachFromSharedMemory();
          DestroySharedMemory();
          return 7;
        } else {
           if ( pid != 0) {
              exit(0); // Terminate the parent
           } else {

              setsid(); // Session leader
#ifndef DEV
              fclose(stderr);
              fclose(stdout);
              fclose(stdin);
#endif

           }
        }


   } else {

#ifdef DEV
     // Log only on development builds
     LogLog("Not becoming a daemon...\n");
#endif

   }

   
   /*****************************************
    * 
    * Register Signal Handlers
    * Daemon probably should ignore ALL signals possible, since termination
    * while active is a bad thing...  however one could check for 
    * any processes active in the shared memory, and destroy the shm if
    * the process wishes to terminate.
    * 
    *****************************************/

   /*   
    *   We have to set up the signal handlers after we daemonize because
    *   the daemonization process redefines our handler for (at least) SIGTERM
    */

   if ( ! SetupSignalHandlers() ) {
     DetachSocketListener(socketfd);
     DestroyMutexes();
     DetachFromSharedMemory();
     DestroySharedMemory();
     return 8;
   }




   /*  ultimatly we will create a couple of threads which monitor the slot db
       and handle the insertion and removal of tokens from the slot.
    */

   /* For Testing the Garbage collection routines */
   /*
      shmp->proc_table[3].inuse = TRUE;
      shmp->proc_table[3].proc_id = 24328;
      */

#if !defined(NOGARBAGE)
printf("Start garbage \n");
   /* start garbage collection thread */
   if ( ! StartGCThread(shmp) ) {
     DetachSocketListener(socketfd);
     DestroyMutexes();
     DetachFromSharedMemory();
     DestroySharedMemory();
     return 9;
   }
#endif

     // We've fully become a daemon.  Now create the PID file
     {
        FILE *pidfile;

        pidfile = fopen(PID_FILE_PATH,"w");
        if (pidfile) {
           fprintf(pidfile,"%d",getpid());
	   fclose(pidfile);
        }
     }

   while (1) {
#if !(THREADED) && !(NOGARBAGE)
     CheckForGarbage(shmp);
#endif

     SocketConnectionHandler(socketfd, 10);

   }


   /*************************************************************
    * 
    *  Here we need to actualy go through the processes and verify that thye
    *  still exist.  If not, then they terminated with out properly calling
    *  C_Finalize and therefore need to be removed from the system.
    *  Look for a system routine to determine if the shared memory is held by 
    *  the process to further verify that the proper processes are in the 
    *  table.
    * 
    *************************************************************/

} /* end main */