|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* COPYRIGHT (c) International Business Machines Corp. 2001-2017
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* This program is provided under the terms of the Common Public License,
|
|
Packit |
8681c6 |
* version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
|
|
Packit |
8681c6 |
* software constitutes recipient's acceptance of CPL-1.0 terms which can be
|
|
Packit |
8681c6 |
* found in the file LICENSE file or at
|
|
Packit |
8681c6 |
* https://opensource.org/licenses/cpl1.0.php
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include <stdlib.h>
|
|
Packit |
8681c6 |
#include <stdio.h>
|
|
Packit |
8681c6 |
#include <errno.h>
|
|
Packit |
8681c6 |
#include <grp.h>
|
|
Packit |
8681c6 |
#include <string.h>
|
|
Packit |
8681c6 |
#include <sys/shm.h>
|
|
Packit |
8681c6 |
#include <sys/stat.h>
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include "slotmgr.h"
|
|
Packit |
8681c6 |
#include "log.h"
|
|
Packit |
8681c6 |
#include "pkcsslotd.h"
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#define MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
|
|
Packit |
8681c6 |
#define MAPFILENAME CONFIG_PATH "/.apimap"
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
pthread_mutexattr_t mtxattr; // Mutex attribute for the shared memory Mutex
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/***********************************************************************
|
|
Packit |
8681c6 |
* CreateSharedMemory -
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* Creates and initializes a shared memory file. This function will fail
|
|
Packit |
8681c6 |
* if the memory is already allocated since we're the owner of it.
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
***********************************************************************/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
int CreateSharedMemory(void)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
struct stat statbuf;
|
|
Packit |
8681c6 |
char *Path = NULL;
|
|
Packit |
8681c6 |
struct group *grp;
|
|
Packit |
8681c6 |
struct shmid_ds shm_info;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#if !MMAP
|
|
Packit Service |
8aa27d |
/*
|
|
Packit Service |
8aa27d |
* getenv() is safe here since we will exclusively create the segment and
|
|
Packit Service |
8aa27d |
* make sure only members of "pkcs11" group can attach to it.
|
|
Packit Service |
8aa27d |
*/
|
|
Packit |
8681c6 |
if (((Path = getenv("PKCS11_SHMEM_FILE")) == NULL) || (Path[0] == '\0')) {
|
|
Packit |
8681c6 |
Path = TOK_PATH;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Get shared memory key token all users of the shared memory
|
|
Packit |
8681c6 |
// need to get the same token
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (stat(Path, &statbuf) < 0) {
|
|
Packit |
8681c6 |
ErrLog("Shared Memory Key Token creation file does not exist");
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// SAB Get the group information for the PKCS#11 group... fail if
|
|
Packit |
8681c6 |
// it does not exist
|
|
Packit |
8681c6 |
grp = getgrnam("pkcs11");
|
|
Packit |
8681c6 |
if (!grp) {
|
|
Packit |
8681c6 |
ErrLog("Group PKCS#11 does not exist ");
|
|
Packit |
8681c6 |
return FALSE; // Group does not exist... setup is wrong..
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tok = ftok(Path, 'b');
|
|
Packit |
8681c6 |
// Allocate the shared memory... Fail if the memory is already
|
|
Packit |
8681c6 |
// allocated since the slot mgr is the owner of it.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Is this some attempt at exclusivity, or is that just a side effect?
|
|
Packit |
8681c6 |
// - SCM 9/1
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
shmid = shmget(tok, sizeof(Slot_Mgr_Shr_t),
|
|
Packit |
8681c6 |
IPC_CREAT | IPC_EXCL | S_IRUSR |
|
|
Packit |
8681c6 |
S_IRGRP | S_IWUSR | S_IWGRP);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Explanation of options to shmget():
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* IPC_CREAT Creates the data structure if it does not already exist.
|
|
Packit |
8681c6 |
* IPC_EXCL Causes the shmget subroutine to be unsuccessful if the
|
|
Packit |
8681c6 |
* IPC_CREAT flag is also set, and the data structure already
|
|
Packit |
8681c6 |
* exists.
|
|
Packit |
8681c6 |
* S_IRUSR Permits the process that owns the data structure to read it.
|
|
Packit |
8681c6 |
* S_IWUSR Permits the process that owns the data structure to modify it.
|
|
Packit |
8681c6 |
* S_IRGRP Permits the group associated with the data structure to
|
|
Packit |
8681c6 |
* read it.
|
|
Packit |
8681c6 |
* S_IWGRP Permits the group associated with the data structure to
|
|
Packit |
8681c6 |
* modify it.
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* WE DON"T WANT OTHERS
|
|
Packit |
8681c6 |
* S_IROTH Permits others to read the data structure.
|
|
Packit |
8681c6 |
* S_IWOTH Permits others to modify the data structure.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (shmid < 0) {
|
|
Packit |
8681c6 |
ErrLog("Shared memory creation failed (0x%X)\n", errno);
|
|
Packit |
8681c6 |
ErrLog("Reclaiming 0x%X\n", tok);
|
|
Packit |
8681c6 |
shmid = shmget(tok, sizeof(Slot_Mgr_Shr_t), 0);
|
|
Packit |
8681c6 |
DestroySharedMemory();
|
|
Packit |
8681c6 |
shmid = shmget(tok, sizeof(Slot_Mgr_Shr_t),
|
|
Packit |
8681c6 |
IPC_CREAT | IPC_EXCL | S_IRUSR |
|
|
Packit |
8681c6 |
S_IRGRP | S_IWUSR | S_IWGRP);
|
|
Packit |
8681c6 |
if (shmid < 0) {
|
|
Packit |
8681c6 |
ErrLog("Shared memory reclamation failed (0x%X)\n", errno);
|
|
Packit |
8681c6 |
ErrLog("perform ipcrm -M 0x%X\n", tok);
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// SAB Set the group ownership of the shared mem segment..
|
|
Packit |
8681c6 |
// we already have the group structure..
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (shmctl(shmid, IPC_STAT, &shm_info) == 0) {
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
shm_info.shm_perm.gid = grp->gr_gid;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (shmctl(shmid, IPC_SET, &shm_info) == -1) {
|
|
Packit |
8681c6 |
ErrLog("Failed to set group ownership for shm \n");
|
|
Packit |
8681c6 |
shmctl(shmid, IPC_RMID, NULL);
|
|
Packit Service |
8aa27d |
// Not safe to use this segment
|
|
Packit Service |
8aa27d |
return FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
ErrLog("Can't get status of shared memory %d\n", errno);
|
|
Packit |
8681c6 |
// we know it was created... we need to destroy it...
|
|
Packit |
8681c6 |
shmctl(shmid, IPC_RMID, NULL);
|
|
Packit Service |
8aa27d |
// Not safe to use this segment
|
|
Packit Service |
8aa27d |
return FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return TRUE;
|
|
Packit |
8681c6 |
#else
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
#warning "EXPERIMENTAL"
|
|
Packit |
8681c6 |
int fd;
|
|
Packit |
8681c6 |
int i;
|
|
Packit |
8681c6 |
char *buffer;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
grp = getgrnam("pkcs11");
|
|
Packit |
8681c6 |
if (!grp) {
|
|
Packit |
8681c6 |
ErrLog("Group \"pkcs11\" does not exist! "
|
|
Packit |
8681c6 |
"Opencryptoki setup is incorrect.");
|
|
Packit |
8681c6 |
return FALSE; // Group does not exist... setup is wrong..
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
fd = open(MAPFILENAME, O_RDWR, MODE);
|
|
Packit |
8681c6 |
if (fd < 0) {
|
|
Packit |
8681c6 |
// File does not exist... this is cool, we creat it here
|
|
Packit |
8681c6 |
fd = open(MAPFILENAME, O_RDWR | O_CREAT, MODE); // Create the file
|
|
Packit |
8681c6 |
if (fd < 0) { // We are really hosed here, since we should be able
|
|
Packit |
8681c6 |
// to create the file now
|
|
Packit |
8681c6 |
ErrLog("%s: open(%s): %s", __func__, MAPFILENAME,
|
|
Packit |
8681c6 |
strerror(errno));
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
if (fchmod(fd, MODE) == -1) {
|
|
Packit |
8681c6 |
ErrLog("%s: fchmod(%s): %s", __func__, MAPFILENAME,
|
|
Packit |
8681c6 |
strerror(errno));
|
|
Packit |
8681c6 |
close(fd);
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (fchown(fd, 0, grp->gr_gid) == -1) {
|
|
Packit |
8681c6 |
ErrLog("%s: fchown(%s, root, pkcs11): %s", __func__,
|
|
Packit |
8681c6 |
MAPFILENAME, strerror(errno));
|
|
Packit |
8681c6 |
close(fd);
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Create a buffer and make the file the right length
|
|
Packit |
8681c6 |
i = sizeof(Slot_Mgr_Shr_t);
|
|
Packit |
8681c6 |
buffer = malloc(sizeof(Slot_Mgr_Shr_t));
|
|
Packit |
8681c6 |
memset(buffer, '\0', i);
|
|
Packit |
8681c6 |
write(fd, buffer, i);
|
|
Packit |
8681c6 |
free(buffer);
|
|
Packit |
8681c6 |
close(fd);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
ErrLog("%s: [%s] exists; you may already have a pkcsslot daemon "
|
|
Packit |
8681c6 |
"running. If this is not the case, then the prior daemon "
|
|
Packit |
8681c6 |
"was not shut down cleanly. Please delete this file and "
|
|
Packit |
8681c6 |
"try again\n", __func__, MAPFILENAME);
|
|
Packit |
8681c6 |
close(fd);
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
return TRUE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/***********************************************************************
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* AttachToSharedMemory -
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* Called after creating the shared memory file
|
|
Packit |
8681c6 |
* Basically allows us to have access to the memory we've just created
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
***********************************************************************/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
int AttachToSharedMemory(void)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#if !MMAP
|
|
Packit |
8681c6 |
shmp = NULL;
|
|
Packit |
8681c6 |
shmp = (Slot_Mgr_Shr_t *) shmat(shmid, NULL, 0);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!shmp) {
|
|
Packit |
8681c6 |
ErrLog("Shared memory attach failed (0x%X)\n", errno);
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Initizalize the memory to 0 */
|
|
Packit |
8681c6 |
memset(shmp, '\0', sizeof(*shmp));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return TRUE;
|
|
Packit |
8681c6 |
#else
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
#warning "EXPERIMENTAL"
|
|
Packit |
8681c6 |
int fd;
|
|
Packit |
8681c6 |
int i;
|
|
Packit |
8681c6 |
char *buffer;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
fd = open(MAPFILENAME, O_RDWR, MODE);
|
|
Packit |
8681c6 |
if (fd < 0) {
|
|
Packit |
8681c6 |
return FALSE; //Failed
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
shmp =
|
|
Packit |
8681c6 |
(Slot_Mgr_Shr_t *) mmap(NULL, sizeof(Slot_Mgr_Shr_t),
|
|
Packit |
8681c6 |
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
Packit |
8681c6 |
close(fd);
|
|
Packit |
8681c6 |
if (!shmp) {
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
return TRUE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/***********************************************************************
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* DetachFromSharedMemory -
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* Un-does AttachToSharedMemory() :)
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
***********************************************************************/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
void DetachFromSharedMemory(void)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#if !MMAP
|
|
Packit |
8681c6 |
if (shmp == NULL)
|
|
Packit |
8681c6 |
return;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (shmdt(shmp) != 0) {
|
|
Packit |
8681c6 |
ErrLog("Attempted to detach from an invalid shared memory pointer");
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
shmp = NULL;
|
|
Packit |
8681c6 |
return;
|
|
Packit |
8681c6 |
#else
|
|
Packit |
8681c6 |
if (shmp == NULL)
|
|
Packit |
8681c6 |
return;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
munmap((void *) shmp, sizeof(*shmp));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
unlink(MAPFILENAME);
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/***********************************************************************
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* DestroySharedMemory -
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* Closes (destroys) the shared memory file we created with
|
|
Packit |
8681c6 |
* CreateSharedMemory()
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* We should make sure that everyone else has detached before we do this
|
|
Packit |
8681c6 |
* if we manage to exit before this gets called, you have to call ipcrm
|
|
Packit |
8681c6 |
* to clean things up...
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
***********************************************************************/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
void DestroySharedMemory(void)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
if (shmctl(shmid, IPC_RMID, 0) != 0) {
|
|
Packit |
8681c6 |
perror("error in closing shared memory segment");
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/***********************************************************************
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* InitSharedMemory -
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* Set up our newly allocated shared memory segment
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
***********************************************************************/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
int InitSharedMemory(Slot_Mgr_Shr_t *sp)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
uint16 procindex;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memset(sp->slot_global_sessions, 0, NUMBER_SLOTS_MANAGED * sizeof(uint32));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Initialize the process side of things. */
|
|
Packit |
8681c6 |
/* for now don't worry about the condition variables */
|
|
Packit |
8681c6 |
for (procindex = 0; procindex < NUMBER_PROCESSES_ALLOWED; procindex++) {
|
|
Packit |
8681c6 |
/* Initialize the mutex variables. */
|
|
Packit |
8681c6 |
sp->proc_table[procindex].inuse = FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return TRUE;
|
|
Packit |
8681c6 |
}
|