Initial changes for Linux port of the CASA-auth-token client to linux.

This commit is contained in:
Juan Carlos Luciani 2006-10-02 21:01:45 +00:00
parent ae9d0c58c5
commit fd8d57708d
27 changed files with 2094 additions and 319 deletions

View File

@ -30,17 +30,6 @@
//===[ Type definitions ]==================================================
//
// Registry Key/Value defines used in the AuthCache
//
#define CASA_AUTH_CACHE_REG_KEY "CASA_Auth_Cache"
#define CREATION_TIME_REG_VALUE "CreationTime"
#define EXPIRATION_TIME_REG_VALUE "ExpirationTime"
#define DOES_NOT_EXPIRE_REG_VALUE "DoesNotExpire"
#define STATUS_REG_VALUE "Status"
#define TOKEN_REG_VALUE "Token"
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
@ -118,13 +107,13 @@ CreateAuthTokenCacheEntry(
if (entryLifetime != 0)
{
pEntry->expirationTime = pEntry->creationTime + (entryLifetime * 1000);
pEntry->doesNotExpire = FALSE;
pEntry->doesNotExpire = false;
}
else
{
// The entry does not expire
pEntry->expirationTime = 0;
pEntry->doesNotExpire = TRUE;
pEntry->doesNotExpire = true;
}
keySize = (uint32_t)strlen(pCacheKey) + (uint32_t)strlen(pGroupOrHostName) + 2;
@ -233,13 +222,13 @@ CreateSessionTokenCacheEntry(
if (entryLifetime != 0)
{
pEntry->expirationTime = pEntry->creationTime + (entryLifetime * 1000);
pEntry->doesNotExpire = FALSE;
pEntry->doesNotExpire = false;
}
else
{
// The entry does not expire
pEntry->expirationTime = 0;
pEntry->doesNotExpire = TRUE;
pEntry->doesNotExpire = true;
}
retStatus = miCASAWriteBinaryKey(g_hCASAContext,
@ -294,7 +283,7 @@ FreeAuthCacheEntry(
//++=======================================================================
static
BOOL
bool
CacheEntryLifetimeExpired(
IN DWORD creationTime,
IN DWORD expirationTime
@ -312,7 +301,7 @@ CacheEntryLifetimeExpired(
//=======================================================================--
{
DWORD currentTime = GetTickCount();
BOOL expired = FALSE;
bool expired = false;
DbgTrace(2, "-CacheEntryLifetimeExpired- Start\n", 0);
@ -329,7 +318,7 @@ CacheEntryLifetimeExpired(
if (currentTime >= expirationTime)
{
// It has expired
expired = TRUE;
expired = true;
}
}
}
@ -341,7 +330,7 @@ CacheEntryLifetimeExpired(
{
// The expiration time did not wrap, therefore
// it has been exceeded since the clock wrapped.
expired = TRUE;
expired = true;
}
else
{
@ -350,7 +339,7 @@ CacheEntryLifetimeExpired(
if (currentTime >= expirationTime)
{
// It has expired
expired = TRUE;
expired = true;
}
}
}
@ -425,7 +414,7 @@ FindSessionTokenEntryInCache(
NULL);
if (CASA_SUCCESS(retStatus))
{
if (pEntry->doesNotExpire == FALSE
if (pEntry->doesNotExpire == false
&& CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime))
{
// Remove the entry ???
@ -525,7 +514,7 @@ FindAuthTokenEntryInCache(
NULL);
if (CASA_SUCCESS(retStatus))
{
if (pEntry->doesNotExpire == FALSE
if (pEntry->doesNotExpire == false
&& CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime))
{
// Remove the entry ???

View File

@ -33,17 +33,20 @@
//===[ Function prototypes ]===============================================
int
InitializeLibrary(void);
//===[ Global variables ]==================================================
//
// Debug tracing level
//
int DebugLevel = 0;
int DebugLevel = 3;
//
// Operating parameter
//
bool g_bInitialized = FALSE;
bool g_bInitialized = false;
bool g_secureRpcSetting = true;
char *g_pATSHostName = NULL;
uint16_t g_ATSPort = 443; // Default HTTPS
@ -498,7 +501,7 @@ ObtainAuthToken(
DbgTrace(1, "-ObtainAuthToken- BufferLength = %d\n", *pAuthTokenBufLen);
// Obtain our synchronization mutex
AcquireInitializationMutex();
AcquireModuleMutex;
// Create user synchronization mutex
retStatus = CreateUserMutex(&hUserMutex);
@ -509,13 +512,13 @@ ObtainAuthToken(
}
// Make sure we are fully initialized
if (g_bInitialized == FALSE)
if (g_bInitialized == false)
{
retStatus = InitializeLibrary();
if (retStatus == CASA_STATUS_SUCCESS)
{
g_bInitialized = TRUE;
g_bInitialized = true;
}
else
{
@ -524,7 +527,7 @@ ObtainAuthToken(
}
// Release our synchronization mutex
ReleaseInitializationMutex();
ReleaseModuleMutex;
// Normalize the host name
pNormalizedHostName = NormalizeHostName(pHostName);
@ -711,34 +714,11 @@ InitializeLibrary(void)
if (CASA_SUCCESS(retStatus))
{
retStatus = InitializeAuthCache();
}
DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
int
Initialize(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
if (CASA_SUCCESS(retStatus))
{
int retStatus;
DbgTrace(1, "-InitializeLibrary- Start\n", 0);
retStatus = CreateInitializationMutex();
retStatus = InitializeRpc();
}
}
DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus);

View File

@ -95,6 +95,19 @@ typedef struct _AuthenticateResp
} AuthenticateResp, *PAuthenticateResp;
//
// Auth Cache Entry definition
//
typedef struct _AuthCacheEntry
{
int status;
DWORD creationTime;
DWORD expirationTime;
bool doesNotExpire;
char token[1];
} AuthCacheEntry, *PAuthCacheEntry;
//===[ Inlines functions ]===============================================
@ -113,21 +126,12 @@ extern char mechConfigFolder[];
extern char pathCharString[];
//===[ External prototypes ]===============================================
//
// Functions exported by engine.c
//
extern
int
Initialize(void);
extern
int
InitializeLibrary(void);
//
// Functions exported by authmech.c
//
@ -231,8 +235,7 @@ CreateSessionTokenCacheEntry(
IN const char *pCacheKey,
IN CasaStatus status,
IN unsigned char *pToken,
IN int entryLifetime
);
IN int entryLifetime);
extern
AuthCacheEntry*
@ -241,8 +244,7 @@ CreateAuthTokenCacheEntry(
IN const char *pHostName,
IN CasaStatus status,
IN unsigned char *pToken,
IN int entryLifetime
);
IN int entryLifetime);
extern
void
@ -303,18 +305,6 @@ DestroyUserMutex(
HANDLE hMutex
);
extern
CasaStatus
CreateInitializationMutex(void);
extern
void
AcquireInitializationMutex(void);
extern
void
ReleaseInitializationMutex(void);
extern
LIB_HANDLE
OpenLibrary(
@ -365,6 +355,10 @@ Rpc(
INOUT char **ppResponseData,
INOUT int *pResponseDataLen);
extern
CasaStatus
InitializeRpc(void);
//
// Defined in utils.c
//

View File

@ -0,0 +1,122 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
if DEBUG
TARGET_CFG = Debug
CFLAGS += -v -w
else
TARGET_CFG = Release
endif
SUBDIRS =
DIST_SUBDIRS =
ROOT = ../..
LIBDIR = $(ROOT)/$(LIB)
# handle Mono secondary dependencies
export MONO_PATH := $(MONO_PATH)
PLATFORMINDEPENDENTSOURCEDIR = ..
PLATFORMDEPENDENTSOURCEDIR = .
MODULE_NAME = libcasa_c_authtoken
MODULE_EXT = so
CFILES = authmech.c \
authmsg.c \
authpolicy.c \
cache.c \
config.c \
engine.c \
getpolicymsg.c \
gettokenmsg.c \
util.c \
rpc.c \
platform.c
CSFILES_CSC :=
INCLUDES = -I. -I.. -I../../include
RESOURCES =
DEFINES = -fno-strict-aliasing
if LIB64
DEFINES += -D_LIB64
endif
CFLAGS += $(INCLUDES) $(DEFINES)
LIBS = -lpthread -ldl -lexpat -lcurl -lidn -lssl -lcrypto -lz -lmicasa
LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT) -L$(ROOT)/lib/$(TARGET_CFG)
OBJDIR = ./$(TARGET_CFG)/$(LIB)
OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o))
EXTRA_DIST = $(CFILES) *.h
CUR_DIR := $(shell pwd)
all: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
#
# Pattern based rules.
#
vpath %.c $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR)
vpath %.cpp $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR)
$(OBJDIR)/%.o: %.c
$(CC) -c $(CFLAGS) -o $@ $<
$(OBJDIR)/%.o: %.cpp
$(CC) -c $(CFLAGS) -o $@ $<
$(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT): $(OBJDIR) $(OBJS)
@echo [======== Linking $@ ========]
$(LINK) -o $@ $(LDFLAGS) $(OBJS) $(LIBS)
cp -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(LIBDIR)/$(TARGET_CFG)/$(MODULE_NAME).$(MODULE_EXT)
$(OBJDIR):
[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
[ -d $(LIBDIR) ] || mkdir -p $(LIBDIR)
[ -d $(LIBDIR)/$(TARGET_CFG) ] || mkdir -p $(LIBDIR)/$(TARGET_CFG)
install-exec-local: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
$(mkinstalldirs) $(DESTDIR)$(libdir)
$(INSTALL_PROGRAM) $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(DESTDIR)$(libdir)/
uninstall-local:
cd $(DESTDIR)$(libdir); rm -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
rmdir $(DESTDIR)$(libdir)
#installcheck-local: install
# $(mkinstalldirs) $(DESTDIR)$(libdir)
# $(INSTALL_PROGRAM) $(DESTDIR)$(libdir)
# cd $(DESTDIR)$(libdir); $(MONO)
clean-local:
if [ -d $(TARGET_CFG) ]; then rm -rf $(TARGET_CFG); fi
distclean-local:
maintainer-clean-local:
rm -f Makefile.in

View File

@ -0,0 +1,829 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//
// Normalized Host Name Cache Entry definition
//
typedef struct _NormalizedHostNameCacheEntry
{
LIST_ENTRY listEntry;
char *pHostName;
char *pNormalizedHostName;
int buffLengthRequired;
} NormalizedHostNameCacheEntry, *PNormalizedHostNameCacheEntry;
//===[ Type definitions for Local_sem ]====================================
//
// Notes: Most of the code for this definitions and the Local_sem_xxxx
// functions was copied with minor modifications from W. Richard
// Stevens book: UNIX Network Programming, Interprocess
// Communications (Printed in 1999).
//
// You may ask, why not just use Posix Named Semaphores? The answer
// is that I wish that I could but I can not tolerate that they are
// not released when the process that holds them terminates abnormally.
//
union semun /* define union for semctl() */
{
int val;
struct semid_ds *buf;
unsigned short *array;
};
typedef struct
{
int sem_semid; /* the System V semaphore ID */
int sem_magic; /* magic number if open */
} Local_sem_t;
#ifndef SEM_R
#define SEM_R 0400
#endif
#ifndef SEM_A
#define SEM_A 0200
#endif
#define SVSEM_MODE (SEM_R | SEM_A | SEM_R>>3 | SEM_R>>6)
#define SEM_MAGIC 0x45678923
#define SEM_FAILED ((Local_sem_t *)(-1)) /* avoid compiler warnings */
#ifndef SEMVMX
#define SEMVMX 32767 /* historical System V max value for sem */
#endif
#define MAX_OPEN_SEM_TRIES 10 /* for waiting for initialization */
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
// Normalized host name cache variables
static
LIST_ENTRY normalizedHostNameCacheListHead;
static
pthread_mutex_t g_hNormalizedHostNameCacheMutex = PTHREAD_MUTEX_INITIALIZER;
// Client configuration file folder
char clientConfigFolder[] = "/etc/CASA/authtoken.d/client.d";
// Authentication mechanism configuration file folder
char mechConfigFolder[] = "/etc/CASA/authtoken.d/client.d/mechanisms.d";
// Module Synchronization mutex
pthread_mutex_t g_hModuleMutex = PTHREAD_MUTEX_INITIALIZER;
// Path separator
char pathCharString[] = "/";
// Milliseconds per System Tick
static
long g_milliSecondsPerTicks = 0;
// Named Semaphore for user variables
static
char g_userNamedSemName[256];
static
Local_sem_t *g_userNamedSem = SEM_FAILED;
static
bool g_userNamedSemAcquired = false;
//++=======================================================================
Local_sem_t*
Local_sem_open(const char *pathname, int oflag, ... )
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes: Most of the code for this routine was copied with minor
// modifications from W. Richard Stevens book: UNIX Network
// Programming, Interprocess Communications (Printed in 1999).
//
//=======================================================================--
{
int i, fd, semflag, semid, save_errno;
key_t key;
mode_t mode;
va_list ap;
Local_sem_t *sem;
union semun arg;
unsigned int value;
struct semid_ds seminfo;
struct sembuf initop;
/* 4no mode for sem_open() w/out O_CREAT; guess */
semflag = SVSEM_MODE;
semid = -1;
if (oflag & O_CREAT) {
va_start(ap, oflag); /* init ap to final named argument */
mode = va_arg(ap, mode_t);
value = va_arg(ap, unsigned int);
va_end(ap);
/* 4convert to key that will identify System V semaphore */
if ( (fd = open(pathname, oflag, mode)) == -1)
return(SEM_FAILED);
close(fd);
if ( (key = ftok(pathname, 0)) == (key_t) -1)
return(SEM_FAILED);
semflag = IPC_CREAT | (mode & 0777);
if (oflag & O_EXCL)
semflag |= IPC_EXCL;
/* 4create the System V semaphore with IPC_EXCL */
if ( (semid = semget(key, 1, semflag | IPC_EXCL)) >= 0) {
/* 4success, we're the first so initialize to 0 */
arg.val = 0;
if (semctl(semid, 0, SETVAL, arg) == -1)
goto err;
/* 4then increment by value to set sem_otime nonzero */
if (value > SEMVMX) {
errno = EINVAL;
goto err;
}
initop.sem_num = 0;
initop.sem_op = value;
initop.sem_flg = 0;
if (semop(semid, &initop, 1) == -1)
goto err;
goto finish;
} else if (errno != EEXIST || (semflag & IPC_EXCL) != 0)
goto err;
/* else fall through */
}
/*
* (O_CREAT not secified) or
* (O_CREAT without O_EXCL and semaphore already exists).
* Must open semaphore and make certain it has been initialized.
*/
if ( (key = ftok(pathname, 0)) == (key_t) -1)
goto err;
if ( (semid = semget(key, 0, semflag)) == -1)
goto err;
arg.buf = &seminfo;
for (i = 0; i < MAX_OPEN_SEM_TRIES; i++) {
if (semctl(semid, 0, IPC_STAT, arg) == -1)
goto err;
if (arg.buf->sem_otime != 0)
goto finish;
sleep(1);
}
errno = ETIMEDOUT;
err:
save_errno = errno; /* don't let semctl() change errno */
if (semid != -1)
semctl(semid, 0, IPC_RMID);
errno = save_errno;
return(SEM_FAILED);
finish:
if ( (sem = malloc(sizeof(Local_sem_t))) == NULL)
goto err;
sem->sem_semid = semid;
sem->sem_magic = SEM_MAGIC;
return(sem);
}
//++=======================================================================
int
Local_sem_wait(Local_sem_t *sem)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes: Most of the code for this routine was copied with minor
// modifications from W. Richard Stevens book: UNIX Network
// Programming, Interprocess Communications (Printed in 1999).
//
//=======================================================================--
{
struct sembuf op;
if (sem->sem_magic != SEM_MAGIC) {
errno = EINVAL;
return(-1);
}
op.sem_num = 0;
op.sem_op = -1;
//op.sem_flg = 0;
op.sem_flg = SEM_UNDO; // Deviation from Richard's to allow cleanup in case of abnormal termination.
if (semop(sem->sem_semid, &op, 1) < 0)
return(-1);
return(0);
}
//++=======================================================================
int
Local_sem_post(Local_sem_t *sem)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes: Most of the code for this routine was copied with minor
// modifications from W. Richard Stevens book: UNIX Network
// Programming, Interprocess Communications (Printed in 1999).
//
//=======================================================================--
{
struct sembuf op;
if (sem->sem_magic != SEM_MAGIC) {
errno = EINVAL;
return(-1);
}
op.sem_num = 0;
op.sem_op = 1;
op.sem_flg = 0;
if (semop(sem->sem_semid, &op, 1) < 0)
return(-1);
return(0);
}
//++=======================================================================
int
Local_sem_close(Local_sem_t *sem)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes: Most of the code for this routine was copied with minor
// modifications from W. Richard Stevens book: UNIX Network
// Programming, Interprocess Communications (Printed in 1999).
//
//=======================================================================--
{
if (sem->sem_magic != SEM_MAGIC) {
errno = EINVAL;
return(-1);
}
sem->sem_magic = 0; /* just in case */
free(sem);
return(0);
}
//++=======================================================================
DWORD
GetTickCount(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L1
//=======================================================================--
{
struct tms tm;
DWORD tickCount;
DbgTrace(2, "-GetTickCount- Start\n", 0);
// Determine milliseconds per tick if we have not done already
if (g_milliSecondsPerTicks == 0)
{
long ticksPerSecond;
ticksPerSecond = sysconf(_SC_CLK_TCK);
DbgTrace(0, "-GetTickCount- TicksPerSec = %0X\n", ticksPerSecond);
g_milliSecondsPerTicks = 1000 / ticksPerSecond;
}
// Determine the tickCount as milliseconds
tickCount = g_milliSecondsPerTicks * times(&tm);
DbgTrace(2, "-GetTickCount- End, retValue = %0X\n", tickCount);
return tickCount;
}
//++=======================================================================
CasaStatus
CreateUserMutex(
HANDLE *phMutex
)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L1
//=======================================================================--
{
CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
DbgTrace(1, "-CreateUserMutex- Start\n", 0);
// We use Posix Named Semaphores to provide this functionality. The semaphore names are
// linked to the user via its uid.
if (sprintf(g_userNamedSemName, "/var/lib/CASA/authtoken/semuser_%d", geteuid()) != -1)
{
// Create or open semaphore to be only used by the effective user
g_userNamedSem = Local_sem_open((const char*) g_userNamedSemName, O_RDWR | O_CREAT, 0600, 1);
if (g_userNamedSem == SEM_FAILED)
{
DbgTrace(0, "-CreateUserMutex- Error opening named semaphore, errno = %d\n", errno);
}
else
{
// Success
retStatus = CASA_STATUS_SUCCESS;
}
}
else
{
DbgTrace(0, "-CreateUserMutex- sprintf failed, error = %d\n", errno);
}
exit:
DbgTrace(1, "-CreateUserMutex- End, retStatus\n", retStatus);
return retStatus;
}
//++=======================================================================
void
AcquireUserMutex(
HANDLE hMutex
)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L1
//=======================================================================--
{
DbgTrace(2, "-AcquireUserMutex- Start\n", 0);
// Wait on the named semaphore
if (Local_sem_wait(g_userNamedSem) != 0)
{
DbgTrace(0, "-AcquireUserMutex- Error returned by sem_wait(), errno = %d\n", errno);
}
// The user semaphore has been acquired
g_userNamedSemAcquired = true;
DbgTrace(2, "-AcquireUserMutex- End\n", 0);
}
//++=======================================================================
void
ReleaseUserMutex(
HANDLE hMutex
)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L1
//=======================================================================--
{
DbgTrace(2, "-ReleaseUserMutex- Start\n", 0);
// The user semaphore is no longer acquired
g_userNamedSemAcquired = false;
// Post on the named semaphore
if (Local_sem_post(g_userNamedSem) != 0)
{
DbgTrace(0, "-ReleaseUserMutex- Error returned by sem_post(), errno = %d\n", errno);
}
DbgTrace(2, "-ReleaseUserMutex- End\n", 0);
}
//++=======================================================================
void
DestroyUserMutex(
HANDLE hMutex
)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L1
//=======================================================================--
{
DbgTrace(2, "-DestroyUserMutex- Start\n", 0);
// Do not do anything if the named semaphore is invalid
if (g_userNamedSem != SEM_FAILED)
{
// Close the named semaphore. Note that we want user semaphores to
// hang around, therefore we will not unlink them. This is per-design as
// is not a resource leak. If someone has an issue with this, then it can
// be solved by installing a cron job that cleans up the semaphores for
// deleted users.
if (LocalSem_close(g_userNamedSem) != 0)
{
DbgTrace(0, "-DestroyUserMutex- Error returned by sem_close(), errno = %d\n", errno);
}
// Forget about the semaphore
g_userNamedSem = SEM_FAILED;
}
DbgTrace(2, "-DestroyUserMutex- End\n", 0);
}
//++=======================================================================
LIB_HANDLE
OpenLibrary(
IN char *pFileName)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
LIB_HANDLE libHandle;
DbgTrace(1, "-OpenLibrary- Start\n", 0);
libHandle = dlopen(pFileName, RTLD_LAZY);
if (libHandle == NULL)
{
DbgTrace(0, "-OpenLibrary- Not able to load library, error = %d\n", dlerror());
}
DbgTrace(1, "-OpenLibrary- End, handle = %08X\n", libHandle);
return libHandle;
}
//++=======================================================================
void
CloseLibrary(
IN LIB_HANDLE libHandle)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
DbgTrace(1, "-CloseLibrary- Start\n", 0);
dlclose(libHandle);
DbgTrace(1, "-CloseLibrary- End\n", 0);
}
//++=======================================================================
void*
GetFunctionPtr(
IN LIB_HANDLE libHandle,
IN char *pFunctionName)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
void *pFuncPtr;
DbgTrace(1, "-GetFunctionPtr- Start\n", 0);
pFuncPtr = dlsym(libHandle, pFunctionName);
if (pFuncPtr == NULL)
{
DbgTrace(0, "-GetFunctionPtr- Not able to obtain func ptr, error = %d\n", dlerror());
}
DbgTrace(1, "-GetFunctionPtr- End, pFuncPtr = %08X\n", pFuncPtr);
return pFuncPtr;
}
//++=======================================================================
char*
NormalizeHostName(
IN const char *pHostName)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L1
//=======================================================================--
{
char *pNormalizedName = NULL;
LIST_ENTRY *pListEntry;
NormalizedHostNameCacheEntry *pEntry = NULL;
DbgTrace(1, "-NormalizeHostName- Start\n", 0);
// Obtain our synchronization mutex
pthread_mutex_lock(&g_hNormalizedHostNameCacheMutex);
// First try to find an entry in the normalized host name cache
// for the host name provided.
pListEntry = normalizedHostNameCacheListHead.Flink;
while (pListEntry != &normalizedHostNameCacheListHead)
{
// Get pointer to the entry
pEntry = CONTAINING_RECORD(pListEntry, NormalizedHostNameCacheEntry, listEntry);
// Check if the entry is for the host name
if (strcmp(pHostName, pEntry->pHostName) == 0)
{
// This entry corresponds to the given host name
break;
}
else
{
// The entry does not correspond to the given host name
pEntry = NULL;
}
// Advance to the next entry
pListEntry = pListEntry->Flink;
}
// Check if we found an entry in our cache for the given host name
if (pEntry)
{
// Entry found, obtain the normalized name from it.
pNormalizedName = (char*) malloc(pEntry->buffLengthRequired);
if (pNormalizedName)
{
// Copy the normalized name onto the allocated buffer
strcpy(pNormalizedName, pEntry->pNormalizedHostName);
}
else
{
DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
}
}
else
{
// An entry was not found in our cache, create one.
pEntry = (NormalizedHostNameCacheEntry*) malloc(sizeof(NormalizedHostNameCacheEntry));
if (pEntry)
{
// Zero the entry
memset(pEntry, 0, sizeof(*pEntry));
// Allocate a buffer to hold the host name in the entry
pEntry->pHostName = (char*) malloc(strlen(pHostName) + 1);
if (pEntry->pHostName)
{
struct hostent *pLookupResult;
struct sockaddr_in sockAddr = {0};
// Copy the host name given into the allocated buffer
strcpy(pEntry->pHostName, pHostName);
// Now try to resolve the normalized name
pLookupResult = gethostbyname(pHostName);
if (pLookupResult && pLookupResult->h_addrtype == AF_INET)
{
char dnsHostName[NI_MAXHOST];
// Set up a sockaddr structure
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = *((int*) pLookupResult->h_addr_list[0]);
// Now try to resolve the name using DNS
if (getnameinfo((const struct sockaddr*) &sockAddr,
sizeof(sockAddr),
dnsHostName,
sizeof(dnsHostName),
NULL,
0,
NI_NAMEREQD) == 0)
{
// We resolved the address to a DNS name, use it as the normalized name.
pEntry->buffLengthRequired = (int) strlen(dnsHostName) + 1;
pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired);
if (pEntry->pNormalizedHostName)
{
// Copy the dns name
strcpy(pEntry->pNormalizedHostName, dnsHostName);
}
else
{
DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
}
}
else
{
DbgTrace(0, "-NormalizeHostName- getnameInfo failed, error %d\n", errno);
// Not able to resolve the name in DNS, just use the host name as
// the normalized name.
pEntry->buffLengthRequired = (int) strlen(pHostName) + 1;
pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired);
if (pEntry->pNormalizedHostName)
{
// Copy the host name
strcpy(pEntry->pNormalizedHostName, pHostName);
}
else
{
DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
}
}
}
else
{
DbgTrace(0, "-NormalizeHostName- Name resolution failed, error = %d\n", errno);
}
}
else
{
DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
// Free the space allocated for the entry
free(pEntry);
}
// Proceed based on whether or not we normalized the name
if (pEntry->pNormalizedHostName)
{
// The name was normalized, save the entry in our cache.
InsertHeadList(&normalizedHostNameCacheListHead, &pEntry->listEntry);
// Return the normalized name present in the entry
pNormalizedName = (char*) malloc(pEntry->buffLengthRequired);
if (pNormalizedName)
{
// Copy the normalized name onto the allocated buffer
strcpy(pNormalizedName, pEntry->pNormalizedHostName);
}
else
{
DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
}
}
else
{
// The host name was not normalized, free allocated resources.
if (pEntry->pHostName)
free(pEntry->pHostName);
free(pEntry);
}
}
else
{
DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0);
}
}
// Release our synchronization mutex
pthread_mutex_unlock(&g_hNormalizedHostNameCacheMutex);
DbgTrace(1, "-NormalizeHostName- End, pNormalizedName = %08X\n", pNormalizedName);
return pNormalizedName;
}
//++=======================================================================
CasaStatus
InitializeHostNameNormalization(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
CasaStatus retStatus = CASA_STATUS_SUCCESS;
DbgTrace(1, "-InitializeHostNameNormalization- Start\n", 0);
// Initialize the cache list head
InitializeListHead(&normalizedHostNameCacheListHead);
DbgTrace(1, "-InitializeHostNameNormalization- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,130 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#define _GNU_SOURCE
//===[ Include files ]=====================================================
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <syslog.h>
#include <pthread.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <dlfcn.h>
#include <unistd.h>
#include <sys/times.h>
#include <fcntl.h>
#include <netdb.h>
#include <curl/curl.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//===[ Type definitions ]==================================================
#ifndef CONTAINING_RECORD
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(char*)(address) - \
(char*)(&((type *)0)->field)))
#endif
//
// DbgTrace macro define
//
#define DbgTrace(LEVEL, X, Y) { \
char printBuff[256]; \
if (LEVEL == 0 || DebugLevel >= LEVEL) \
{ \
_snprintf(printBuff, sizeof(printBuff), X, Y); \
fprintf(stderr, "CASA_AuthToken %s", printBuff); \
} \
}
/*#define DbgTrace(LEVEL, X, Y) { \
if (LEVEL == 0 || DebugLevel >= LEVEL) \
{ \
openlog("CASA_AuthToken", LOG_CONS | LOG_NOWAIT | LOG_ODELAY, LOG_USER); \
syslog(LOG_USER | LOG_INFO, X, Y); \
closelog(); \
} \
}*/
//
// Rpc Session definition
//
typedef struct _RpcSession
{
CURL *hCurl;
char *pPartialHttpUrl;
int partialHttpUrlLen;
char *pPartialHttpsUrl;
int partialHttpsUrlLen;
struct curl_slist *headers;
char *pRecvData;
int recvDataLen;
} RpcSession, *PRpcSession;
//
// Other definitions
//
#define HANDLE void*
#define LIB_HANDLE void*
#define DWORD unsigned long
#define AcquireModuleMutex pthread_mutex_lock(&g_hModuleMutex)
#define ReleaseModuleMutex pthread_mutex_unlock(&g_hModuleMutex)
//
// Deal with function name mapping issues
//
#define _snprintf snprintf
#define stricmp strcasecmp
//===[ Inlines functions ]===============================================
//===[ Function prototypes ]===============================================
//===[ Global externals ]==================================================
//===[ External prototypes ]===============================================
extern
DWORD
GetTickCount(void);
//===[ External data ]=====================================================
extern pthread_mutex_t g_hModuleMutex;
//=========================================================================

View File

@ -0,0 +1,539 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
#define INITIAL_RESPONSE_DATA_BUF_SIZE 1028
#define INCREMENT_RESPONSE_DATA_BUF_SIZE 256
#define MAX_RPC_RETRIES 3
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
//++=======================================================================
size_t
CurlWriteCallback(
IN void *pData,
IN size_t dataItemSz,
IN size_t numDataItems,
IN RpcSession *pSession)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L0
//=======================================================================--
{
size_t dataConsumed = numDataItems;
DbgTrace(1, "-CurlWriteCallback- Start\n", 0);
// Consume the data by keeping a copy of the data. Note that we may have
// already consumed some data in which case we need to allocate a new
// buffer big enough to hold all of it.
if (pSession->pRecvData == NULL)
{
// We have not yet consumed receive data for the current Rpc
pSession->pRecvData = (char*) malloc(numDataItems * dataItemSz);
if (pSession->pRecvData)
{
// Consume the data
memcpy(pSession->pRecvData, pData, numDataItems * dataItemSz);
pSession->recvDataLen = numDataItems * dataItemSz;
}
else
{
DbgTrace(0, "-CurlWriteCallback- Buffer allocation error\n", 0);
dataConsumed = CURLE_WRITE_ERROR; // To abort RPC
}
}
else
{
// We have already consumed receive data for the current Rpc, append the new data to it.
char *pNewRecvDataBuf = (char*) malloc(pSession->recvDataLen + (numDataItems * dataItemSz));
if (pNewRecvDataBuf)
{
memcpy(pNewRecvDataBuf, pSession->pRecvData, pSession->recvDataLen);
memcpy(pNewRecvDataBuf + pSession->recvDataLen, pData, numDataItems * dataItemSz);
pSession->recvDataLen += numDataItems * dataItemSz;
free(pSession->pRecvData);
pSession->pRecvData = pNewRecvDataBuf;
}
else
{
DbgTrace(0, "-CurlWriteCallback- Buffer allocation error\n", 0);
dataConsumed = CURLE_WRITE_ERROR; // To abort RPC
// Forget about already consumed data
free(pSession->pRecvData);
pSession->pRecvData = NULL;
}
}
DbgTrace(1, "-CurlWriteCallback- End\n", 0);
return dataConsumed;
}
//++=======================================================================
RpcSession*
OpenRpcSession(
IN char *pHostName,
IN uint16_t hostPort)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L0
//=======================================================================--
{
RpcSession *pSession;
char *pPartialHttpUrl = NULL;
char *pPartialHttpsUrl = NULL;
int hostNameLen = strlen(pHostName);
DbgTrace(1, "-OpenRpcSession- Start\n", 0);
// Build the partial URL strings that may be used with this session.
pPartialHttpUrl = (char*) malloc(7 /*"http://"*/ + hostNameLen + 34 /*":XXXX/CasaAuthTokenSvc/Rpc?method="*/ + 1 /*NULL Terminator*/);
pPartialHttpsUrl = (char*) malloc(8 /*"https://"*/ + hostNameLen + 34 /*":XXXX/CasaAuthTokenSvc/Rpc?method="*/ + 1 /*NULL Terminator*/);
if (pPartialHttpUrl && pPartialHttpsUrl)
{
sprintf(pPartialHttpUrl, "http://%s:%d/CasaAuthTokenSvc/Rpc?method=", pHostName, hostPort);
sprintf(pPartialHttpsUrl, "https://%s:%d/CasaAuthTokenSvc/Rpc?method=", pHostName, hostPort);
// Allocate space for the session
pSession = (RpcSession*) malloc(sizeof(*pSession));
if (pSession)
{
// Zero the session structure
memset(pSession, 0, sizeof(*pSession));
// Get a curl handle
pSession->hCurl = curl_easy_init();
if (pSession->hCurl != NULL)
{
CURLcode result;
bool setOptError = false;
// Set necessary options on the handle
if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_NOSIGNAL, 0)) != CURLE_OK)
{
DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_NOSIGNAL, code = %d\n", result);
setOptError = true;
}
if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_USERAGENT, "CASA Client/1.0")) != CURLE_OK)
{
DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_USERAGENT, code = %d\n", result);
setOptError = true;
}
if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_POST, 1)) != CURLE_OK)
{
DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_POST, code = %d\n", result);
setOptError = true;
}
pSession->headers = curl_slist_append(pSession->headers, "Content-Type: text/html");
pSession->headers = curl_slist_append(pSession->headers, "Expect:");
if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_HTTPHEADER, pSession->headers)) != CURLE_OK)
{
DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_HTTPHEADER, code = %d\n", result);
setOptError = true;
}
if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_WRITEFUNCTION, CurlWriteCallback)) != CURLE_OK)
{
DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_WRITEFUNCTION, code = %d\n", result);
setOptError = true;
}
if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_WRITEDATA, pSession)) != CURLE_OK)
{
DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_WRITEDATA, code = %d\n", result);
setOptError = true;
}
// Now check if we succeded
if (setOptError == false)
{
// Success, finish setting up the session object.
pSession->pPartialHttpUrl = pPartialHttpUrl;
pSession->partialHttpUrlLen = strlen(pPartialHttpUrl);
pSession->pPartialHttpsUrl = pPartialHttpsUrl;
pSession->partialHttpsUrlLen = strlen(pPartialHttpsUrl);
// Forget about the partial URL buffers so that they do not get deleted below
pPartialHttpUrl = NULL;
pPartialHttpsUrl = NULL;
}
else
{
// Failed to set a needed curl option
if (pSession->headers)
curl_slist_free_all(pSession->headers);
curl_easy_cleanup(pSession->hCurl);
free(pSession);
pSession = NULL;
}
}
else
{
DbgTrace(0, "-OpenRpcSession- Error creating curl handle\n", 0);
free(pSession);
pSession = NULL;
}
}
else
{
DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for rpc session\n", 0);
}
}
else
{
DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for URL\n", 0);
}
// Free buffers not utilized
if (pPartialHttpUrl)
free(pPartialHttpUrl);
if (pPartialHttpsUrl)
free(pPartialHttpsUrl);
DbgTrace(2, "-OpenRpcSession- End, pSession = %08X\n", pSession);
return pSession;
}
//++=======================================================================
void
CloseRpcSession(
IN RpcSession *pSession)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L1
//=======================================================================--
{
DbgTrace(1, "-CloseRpcSession- Start\n", 0);
// Free any HTTP headers associated with the session
if (pSession->headers)
curl_slist_free_all(pSession->headers);
// Close the curl handle associated with this session
curl_easy_cleanup(pSession->hCurl);
// Free the space allocated for the session
if (pSession->pRecvData)
free(pSession->pRecvData);
free(pSession->pPartialHttpUrl);
free(pSession->pPartialHttpsUrl);
free(pSession);
DbgTrace(1, "-CloseRpcSession- End\n", 0);
}
//++=======================================================================
static
CasaStatus
InternalRpc(
IN RpcSession *pSession,
IN char *pMethod,
IN bool secure,
IN char *pRequestData,
INOUT char **ppResponseData,
INOUT int *pResponseDataLen)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L1
//=======================================================================--
{
CasaStatus retStatus;
char *pPartialUrl;
int partialUrlLen;
char *pUrl;
CURLcode curlResult;
DbgTrace(1, "-InternalRpc- Start\n", 0);
// Initialize output parameters
*ppResponseData = NULL;
*pResponseDataLen = 0;
// Setup the final URL using the input parameters
if (secure)
{
pPartialUrl = pSession->pPartialHttpsUrl;
partialUrlLen = pSession->partialHttpsUrlLen;
}
else
{
pPartialUrl = pSession->pPartialHttpUrl;
partialUrlLen = pSession->partialHttpUrlLen;
}
pUrl = (char*) malloc(partialUrlLen + strlen(pMethod) + 1);
if (pUrl)
{
strcpy(pUrl, pPartialUrl);
strcat(pUrl, pMethod);
// Tell curl about the URL
curlResult = curl_easy_setopt(pSession->hCurl, CURLOPT_URL, pUrl);
if (curlResult == CURLE_OK)
{
// Tell curl about our post data
curlResult = curl_easy_setopt(pSession->hCurl, CURLOPT_POSTFIELDS, pRequestData);
if (curlResult == CURLE_OK)
{
// Tell curl about our post data len
curlResult = curl_easy_setopt(pSession->hCurl, CURLOPT_POSTFIELDSIZE, strlen(pRequestData));
if (curlResult == CURLE_OK)
{
// Now do the HTTP request
curlResult = curl_easy_perform(pSession->hCurl);
if (curlResult == CURLE_OK)
{
// Get the HTTP Response code
long httpCompStatus;
curlResult = curl_easy_getinfo(pSession->hCurl, CURLINFO_RESPONSE_CODE, &httpCompStatus);
if (curlResult == CURLE_OK)
{
// Verify that the HTTP request was successfully completed by the server
if (httpCompStatus == 200)
{
// Success, return the response data to the caller.
retStatus = CASA_STATUS_SUCCESS;
*ppResponseData = pSession->pRecvData;
*pResponseDataLen = pSession->recvDataLen;;
// Forget about the response data buffer to keep from freeing it.
pSession->pRecvData = NULL;
}
else
{
DbgTrace(0, "-InternalRpc- HTTP request did not complete successfully, status = %d\n", httpCompStatus);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
}
else
{
DbgTrace(0, "-OpenRpcSession- Curl get info failed, code = %d\n", curlResult);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
}
else
{
DbgTrace(0, "-OpenRpcSession- Curl perform failed, code = %d\n", curlResult);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
// Make sure that we never exit with a recv data buffer hanging off the session
if (pSession->pRecvData)
{
free(pSession->pRecvData);
pSession->pRecvData = NULL;
}
}
else
{
DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_POSTFIELDSIZE, code = %d\n", curlResult);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
}
else
{
DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_POSTFIELDS, code = %d\n", curlResult);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
}
else
{
DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_URL, code = %d\n", curlResult);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
// Free the buffer used to hold the URL
free(pUrl);
}
else
{
DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
DbgTrace(1, "-InternalRpc- End, retStatus = %d\n", retStatus);
return retStatus;
}
//++=======================================================================
CasaStatus
Rpc(
IN RpcSession *pSession,
IN char *pMethod,
IN bool secure,
IN char *pRequestData,
INOUT char **ppResponseData,
INOUT int *pResponseDataLen)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
int retries = 0;
DbgTrace(1, "-Rpc- Start\n", 0);
// Retry the RPC as needed
do
{
// Issue the RPC
retStatus = InternalRpc(pSession,
pMethod,
secure,
pRequestData,
ppResponseData,
pResponseDataLen);
// Account for this try
retries ++;
} while (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE
&& retries < MAX_RPC_RETRIES);
DbgTrace(1, "-Rpc- End, retStatus = %d\n", retStatus);
return retStatus;
}
//++=======================================================================
CasaStatus
InitializeRpc(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L0
//=======================================================================--
{
CasaStatus retStatus;
DbgTrace(1, "-InitializeRpc- Start\n", 0);
// Perform libcurl initializatoin
CURLcode curlStatus = curl_global_init(CURL_GLOBAL_SSL);
if (curlStatus != 0)
{
DbgTrace(0, "-InitializeRpc- Error initializing libcurl, curlStatus = %08X\n", curlStatus);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
else
{
// Success
retStatus = CASA_STATUS_SUCCESS;
}
DbgTrace(1, "-InitializeRpc- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,37 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = krb5 pwd
DIST_SUBDIRS = krb5 pwd
CFILES =
EXTRA_DIST = $(CFILES) *.h
.PHONY: package package-clean package-install package-uninstall
package package-clean package-install package-uninstall:
$(MAKE) -C $(TARGET_OS) $@
maintainer-clean-local:
rm -f Makefile.in

View File

@ -0,0 +1,37 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = $(TARGET_OS)
DIST_SUBDIRS = linux
CFILES = *.c
EXTRA_DIST = $(CFILES) *.h
.PHONY: package package-clean package-install package-uninstall
package package-clean package-install package-uninstall:
$(MAKE) -C $(TARGET_OS) $@
maintainer-clean-local:
rm -f Makefile.in

View File

@ -72,7 +72,6 @@ GetUserCredentials(
SSCS_SECRET_ID_T secretId = {0};
SSCS_SECRET_ID_T sharedSecretId = {0};
DbgTrace(1, "-GetUserCredentials- Start\n", 0);
// Initialize output parameters
@ -332,33 +331,6 @@ exit:
}
//++=======================================================================
int
InitializeLibrary(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
int retStatus = 0;
DbgTrace(1, "-InitializeLibrary- Start\n", 0);
// Nothing to do at this time.
DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -62,10 +62,6 @@ AuthTokenIf_GetAuthToken(
INOUT char *pTokenBuf,
INOUT int *pTokenBufLen);
extern
int
InitializeLibrary(void);
//
// Defined in utils.c
//

View File

@ -0,0 +1,114 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
if DEBUG
TARGET_CFG = Debug
CFLAGS += -v -w
else
TARGET_CFG = Release
endif
SUBDIRS =
DIST_SUBDIRS =
ROOT = ../../../..
LIBDIR = $(ROOT)/$(LIB)
# handle Mono secondary dependencies
export MONO_PATH := $(MONO_PATH)
PLATFORMINDEPENDENTSOURCEDIR = ..
PLATFORMDEPENDENTSOURCEDIR = .
MODULE_NAME = pwmech
MODULE_EXT = so
CFILES = get.c \
interface.c \
util.c \
platform.c
CSFILES_CSC :=
INCLUDES = -I. -I.. -I../../.. -I$(ROOT)/include
RESOURCES =
DEFINES = -fno-strict-aliasing
if LIB64
DEFINES += -D_LIB64
endif
CFLAGS += $(INCLUDES) $(DEFINES)
LIBS = -lpthread -lmicasa
LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT) -L$(ROOT)/lib/$(TARGET_CFG)
OBJDIR = ./$(TARGET_CFG)/$(LIB)
OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o))
EXTRA_DIST = $(CFILES) *.h PwdAuthenticate.conf
CUR_DIR := $(shell pwd)
all: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
#
# Pattern based rules.
#
vpath %.c $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR)
vpath %.cpp $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR)
$(OBJDIR)/%.o: %.c
$(CC) -c $(CFLAGS) -o $@ $<
$(OBJDIR)/%.o: %.cpp
$(CC) -c $(CFLAGS) -o $@ $<
$(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT): $(OBJDIR) $(OBJS)
@echo [======== Linking $@ ========]
$(LINK) -o $@ $(LDFLAGS) $(OBJS) $(LIBS)
cp -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(LIBDIR)/$(TARGET_CFG)/$(MODULE_NAME).$(MODULE_EXT)
$(OBJDIR):
[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
[ -d $(LIBDIR) ] || mkdir -p $(LIBDIR)
[ -d $(LIBDIR)/$(TARGET_CFG) ] || mkdir -p $(LIBDIR)/$(TARGET_CFG)
install-exec-local: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
$(mkinstalldirs) $(DESTDIR)$(libdir)
$(INSTALL_PROGRAM) $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(DESTDIR)$(libdir)/
uninstall-local:
cd $(DESTDIR)$(libdir); rm -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
rmdir $(DESTDIR)$(libdir)
#installcheck-local: install
# $(mkinstalldirs) $(DESTDIR)$(libdir)
# $(INSTALL_PROGRAM) $(DESTDIR)$(libdir)
# cd $(DESTDIR)$(libdir); $(MONO)
clean-local:
if [ -d $(TARGET_CFG) ]; then rm -rf $(TARGET_CFG); fi
distclean-local:
maintainer-clean-local:
rm -f Makefile.in

View File

@ -0,0 +1,12 @@
#######################################################
# #
# CASA Authentication Token System configuration file #
# for module: #
# #
# PwdAuthenticate #
# #
#######################################################
LibraryName /usr/lib/CASA/authtoken/pwmech.so

View File

@ -0,0 +1,35 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================

View File

@ -0,0 +1,88 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#define _GNU_SOURCE
//===[ Include files ]=====================================================
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <syslog.h>
#include <pthread.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
//===[ Type definitions ]==================================================
#define HANDLE void*
#ifndef CONTAINING_RECORD
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(char*)(address) - \
(char*)(&((type *)0)->field)))
#endif
//
// DbgTrace macro define
//
#define DbgTrace(LEVEL, X, Y) { \
char printBuff[256]; \
if (LEVEL == 0 || DebugLevel >= LEVEL) \
{ \
_snprintf(printBuff, sizeof(printBuff), X, Y); \
fprintf(stderr, "CASA_PwMech %s", printBuff); \
} \
}
/*#define DbgTrace(LEVEL, X, Y) { \
if (LEVEL == 0 || DebugLevel >= LEVEL) \
{ \
openlog("CASA_PwMech", LOG_CONS | LOG_NOWAIT | LOG_ODELAY, LOG_USER); \
syslog(LOG_USER | LOG_INFO, X, Y); \
closelog(); \
} \
}*/
//
// Deal with function name mapping issues
//
#define _snprintf snprintf
//===[ Inlines functions ]===============================================
//===[ Function prototypes ]===============================================
//===[ Global externals ]==================================================
//===[ External prototypes ]===============================================
//=========================================================================

View File

@ -33,7 +33,7 @@
//===[ Global variables ]==================================================
// Debug Level
int DebugLevel = 0;
int DebugLevel = 3;
// Tables for Base64 encoding and decoding
static const int8_t g_Base64[] =

View File

@ -57,13 +57,7 @@ BOOL APIENTRY DllMain(
{
g_hModule = hModule;
// Initialize the library
if (InitializeLibrary() != 0)
{
// Failed to initialize the library
OutputDebugString("CASA_PW_MECH -DllMain- Library initialization failed\n");
retStatus = FALSE;
}
// Nothing else to do at this time
break;
}

View File

@ -55,7 +55,7 @@ char formatBuff[128]; \
char printBuff[256]; \
if (LEVEL == 0 || DebugLevel >= LEVEL) \
{ \
strcpy(formatBuff, "PwdMech "); \
strcpy(formatBuff, "CASA_PwdMech "); \
strncat(formatBuff, X, sizeof(formatBuff) - 8); \
_snprintf(printBuff, sizeof(printBuff), formatBuff, Y); \
OutputDebugString(printBuff); \

View File

@ -46,6 +46,7 @@ char mechConfigFolderPartialPath[];
UINT32 g_ulCount = 0;
UINT32 g_ulLock = 0;
HANDLE g_hModule;
HANDLE g_hModuleMutex;
//++=======================================================================
@ -78,11 +79,12 @@ BOOL APIENTRY DllMain(
strcpy(mechConfigFolder, programFilesFolder);
PathAppend(mechConfigFolder, mechConfigFolderPartialPath);
// Initialize the library
if (Initialize() != 0)
// Allocate module mutex
g_hModuleMutex = CreateMutex(NULL, FALSE, NULL);
if (! g_hModuleMutex)
{
// Failed to initialize the library
OutputDebugString("CASAAUTH -DllMain- Library initialization failed\n");
// Module initialization failed
OutputDebugString("CASAAUTH -DllMain- Failed to create mutex\n");
retStatus = FALSE;
}
}

View File

@ -61,10 +61,6 @@ char clientConfigFolderPartialPath[] = "Novell\\Casa\\Etc\\Auth";
char mechConfigFolder[MAX_PATH];
char mechConfigFolderPartialPath[] = "Novell\\Casa\\Etc\\Auth\\Mechanisms";
// Synchronization mutex for the dll initialization
static
HANDLE g_hInitializationMutex;
// Path separator
char pathCharString[] = "\\";
@ -117,7 +113,7 @@ CreateUserMutex(
mutexName);
if (*phMutex == NULL)
{
DbgTrace(0, "-CreateUserMutex- CreteMutex failed, error = %d\n", GetLastError());
DbgTrace(0, "-CreateUserMutex- CreateMutex failed, error = %d\n", GetLastError());
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
@ -245,89 +241,6 @@ DestroyUserMutex(
}
//++=======================================================================
CasaStatus
CreateInitializationMutex(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
int retStatus = -1;
DbgTrace(2, "-CreateInitializationMutex- Start\n", 0);
// Create a cache mutex only applicable to the current process
g_hInitializationMutex = CreateMutex(NULL, FALSE, NULL);
if (g_hInitializationMutex != NULL)
{
retStatus = CASA_STATUS_SUCCESS;
}
DbgTrace(2, "-CreateInitializationMutex- End\n", 0);
return retStatus;
}
//++=======================================================================
void
AcquireInitializationMutex(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
DbgTrace(2, "-AcquireInitializationMutex- Start\n", 0);
WaitForSingleObject(g_hInitializationMutex, INFINITE);
DbgTrace(2, "-AcquireInitializationMutex- End\n", 0);
}
//++=======================================================================
void
ReleaseInitializationMutex(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
DbgTrace(2, "-ReleaseInitializationMutex- Start\n", 0);
if (ReleaseMutex(g_hInitializationMutex) == 0)
{
DbgTrace(0, "-ReleaseInitializationMutex- ReleaseMutex failed, error\n", 0);
}
DbgTrace(2, "-ReleaseInitializationMutex- End\n", 0);
}
//++=======================================================================
LIB_HANDLE
OpenLibrary(
@ -346,7 +259,6 @@ OpenLibrary(
{
LIB_HANDLE libHandle;
DbgTrace(1, "-OpenLibrary- Start\n", 0);
libHandle = LoadLibrary(pFileName);
@ -404,7 +316,6 @@ GetFunctionPtr(
{
void *pFuncPtr;
DbgTrace(1, "-GetFunctionPtr- Start\n", 0);
pFuncPtr = GetProcAddress(libHandle, pFunctionName);
@ -439,7 +350,6 @@ NormalizeHostName(
LIST_ENTRY *pListEntry;
NormalizedHostNameCacheEntry *pEntry = NULL;
DbgTrace(1, "-NormalizeHostName- Start\n", 0);
// Obtain our synchronization mutex

View File

@ -49,7 +49,7 @@
// if (LEVEL == 0 || DebugLevel >= LEVEL) \
// { \
// _snprintf(printBuff, sizeof(printBuff), X, Y); \
// printf("AuthToken %s", printBuff); \
// printf("CASA_AuthToken %s", printBuff); \
// } \
//}
#define DbgTrace(LEVEL, X, Y) { \
@ -57,35 +57,13 @@ char formatBuff[128]; \
char printBuff[256]; \
if (LEVEL == 0 || DebugLevel >= LEVEL) \
{ \
strcpy(formatBuff, "AuthToken "); \
strcpy(formatBuff, "CASA_AuthToken "); \
strncat(formatBuff, X, sizeof(formatBuff) - 10); \
_snprintf(printBuff, sizeof(printBuff), formatBuff, Y); \
OutputDebugString(printBuff); \
} \
}
#define bool BOOLEAN
#define true TRUE
#define false FALSE
//
// Auth Cache Entry definition
//
typedef struct _AuthCacheEntry
{
// LIST_ENTRY listEntry;
// int refCount;
int status;
DWORD creationTime;
DWORD expirationTime;
BOOL doesNotExpire;
// char *pHostName;
// char *pCacheKeyName;
char token[1];
} AuthCacheEntry, *PAuthCacheEntry;
//
// Rpc Session definition
//
@ -96,11 +74,18 @@ typedef struct _RpcSession
} RpcSession, *PRpcSession;
//
// Other definitions
//
#define LIB_HANDLE HMODULE
#define bool BOOLEAN
#define true TRUE
#define false FALSE
#define long DWORD
#define AcquireModuleMutex WaitForSingleObjectEx(g_hModuleMutex, INFINITE, FALSE)
#define ReleaseModuleMutex ReleaseMutex(g_hModuleMutex)
//===[ Inlines functions ]===============================================
@ -110,5 +95,9 @@ typedef struct _RpcSession
//===[ External prototypes ]===============================================
//===[ External data ]=====================================================
extern HANDLE g_hModuleMutex;
//=========================================================================

View File

@ -287,5 +287,10 @@ server/PamSupport/linux/Makefile
server/ApacheSupport/Makefile
server/ApacheSupport/2.2/Makefile
server/ApacheSupport/2.2/linux/Makefile
client/Makefile
client/linux/Makefile
client/mechanisms/Makefile
client/mechanisms/pwd/Makefile
client/mechanisms/pwd/linux/Makefile
])

View File

@ -199,7 +199,6 @@ OpenLibrary(
{
LIB_HANDLE libHandle;
DbgTrace(1, "-OpenLibrary- Start\n", 0);
libHandle = dlopen(pFileName, RTLD_LAZY);

View File

@ -96,5 +96,7 @@ extern pthread_mutex_t g_hModuleMutex;
//===[ External prototypes ]===============================================
//=========================================================================