int DestroyMutexes ( void ) { /* Get the global shared memory mutex */ XProcLock(); /* Give up the global shared memory mutex */ XProcUnLock(); return TRUE; }
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; }
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 */