From 0c45cbb4ef606b2e7e1d1fc24b24040cd3c365c3 Mon Sep 17 00:00:00 2001 From: Juan Carlos Luciani Date: Wed, 4 Oct 2006 20:41:00 +0000 Subject: [PATCH] Port of client Krb5 Auth Mechanism to Linux. --- .../krb5/linux/Krb5Authenticate.conf | 12 + .../client/mechanisms/krb5/linux/Makefile.am | 114 ++++++ .../client/mechanisms/krb5/linux/get.c | 351 ++++++++++++++++++ .../client/mechanisms/krb5/linux/platform.c | 35 ++ .../client/mechanisms/krb5/linux/platform.h | 90 +++++ .../krb5/windows/Krb5Authenticate.conf | 24 +- .../client/mechanisms/krb5/windows/get.c | 1 - CASA-auth-token/non-java/configure.in | 2 + 8 files changed, 616 insertions(+), 13 deletions(-) create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/linux/Krb5Authenticate.conf create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/linux/Makefile.am create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/linux/get.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/linux/platform.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/linux/platform.h diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/linux/Krb5Authenticate.conf b/CASA-auth-token/non-java/client/mechanisms/krb5/linux/Krb5Authenticate.conf new file mode 100644 index 00000000..df2ad167 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/linux/Krb5Authenticate.conf @@ -0,0 +1,12 @@ +####################################################### +# # +# CASA Authentication Token System configuration file # +# for module: # +# # +# Krb5Authenticate # +# # +####################################################### + +LibraryName /usr/lib/CASA/authtoken/krb5mech.so + + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/linux/Makefile.am b/CASA-auth-token/non-java/client/mechanisms/krb5/linux/Makefile.am new file mode 100644 index 00000000..9866aed4 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/linux/Makefile.am @@ -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 +# +####################################################################### + +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 = krb5mech +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 -lc -lgssapi +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 Krb5Authenticate.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 + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/linux/get.c b/CASA-auth-token/non-java/client/mechanisms/krb5/linux/get.c new file mode 100644 index 00000000..07edfa49 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/linux/get.c @@ -0,0 +1,351 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Mechanism OID +gss_OID g_mechOid = GSS_C_NULL_OID; + + +//++======================================================================= +void +LogGssStatuses( + IN char *operation, + IN OM_uint32 majorGssStatus, + IN OM_uint32 minorGssStatus) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + OM_uint32 gssMajStat; + OM_uint32 gssMinStat; + gss_buffer_desc msg = GSS_C_EMPTY_BUFFER; + OM_uint32 gssMsgCtx; + + // Trace the messages associated with the major status + gssMsgCtx = 0; + while (1) + { + gssMajStat = gss_display_status(&gssMinStat, + majorGssStatus, + GSS_C_GSS_CODE, + g_mechOid, + &gssMsgCtx, + &msg); + if (gssMajStat != GSS_S_COMPLETE) + { + DbgTrace(0, "-LogGssStatuses- Error obtaining display status\n", 0); + break; + } + + // Trace this message + DbgTrace(0, "-LogGssStatuses- GSS-API error %s: ", operation); + DbgTrace(0, "%s\n", (char *)msg.value); + + if (msg.length != 0) + gss_release_buffer(&gssMinStat, &msg); + + if (!gssMsgCtx) + break; + } + + // Trace the messages associated with the minor status + gssMsgCtx = 0; + while (1) + { + gssMajStat = gss_display_status(&gssMinStat, + minorGssStatus, + GSS_C_MECH_CODE, + g_mechOid, + &gssMsgCtx, + &msg); + if (gssMajStat != GSS_S_COMPLETE) + { + DbgTrace(0, "-LogGssStatuses- Error obtaining display status\n", 0); + break; + } + + // Trace this message + DbgTrace(0, "-LogGssStatuses- GSS-API error %s: ", operation); + DbgTrace(0, "%s\n", (char *)msg.value); + + if (msg.length != 0) + gss_release_buffer(&gssMinStat, &msg); + + if (!gssMsgCtx) + break; + } +} + + +//++======================================================================= +CasaStatus SSCS_CALL +AuthTokenIf_GetAuthToken( + IN const void *pIfInstance, + IN const char *pContext, + IN const char *pMechInfo, + INOUT char *pTokenBuf, + INOUT int *pTokenBufLen) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// pServiceConfigIf - +// Pointer to service config object to which the client is trying to +// authenticate. +// +// pContext - +// Pointer to null terminated string containing mechanism specific +// context information. Another name for context is Authentication +// Realm. +// +// pMechInfo - +// Pointer to null terminated string containing mechanism specific +// information. This is information is provided by the server to +// aid the mechanism to generate an authentication token. For +// example, the mechanism information for a Kerberos mechanism +// may be the service principal name to which the user will be +// authenticating. +// +// pTokenBuf - +// Pointer to buffer that will receive the authentication +// token. The length of this buffer is specified by the +// pTokenBufLen parameter. Note that the the authentication +// token will be in the form of a NULL terminated string. +// +// pTokenBufLen - +// Pointer to integer that contains the length of the +// buffer pointed at by pTokenBuf. Upon return of the +// function, the integer will contain the actual length +// of the authentication token if the function successfully +// completes or the buffer length required if the function +// fails because the buffer pointed at by pUserNameBuf is +// not large enough. +// +// Returns: +// Casa Status +// +// Description: +// Get authentication token to authenticate user to specified service. +// +// L0 +//=======================================================================-- +{ + CasaStatus retStatus; + char *pKrbServiceName = pMechInfo; + OM_uint32 gssMajStat; + OM_uint32 gssMinStat; + gss_buffer_desc gssBuffer; + gss_name_t gssServiceName; + + DbgTrace(1, "-AuthTokenIf_GetAuthToken- Start\n", 0); + + // Validate input parameters + if (pIfInstance == NULL + || pContext == NULL + || pMechInfo == NULL + || pTokenBufLen == NULL + || (pTokenBuf == NULL && *pTokenBufLen != 0)) + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Invalid input parameter\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_INVALID_PARAMETER); + goto exit; + } + + // Import the service principal name into something that + // GSS-API can understand based on its form. + gssBuffer.value = (void*) pKrbServiceName; + gssBuffer.length = strlen(pKrbServiceName) + 1; + if (strchr(pKrbServiceName, '@') != NULL) + { + // The name is of the form "servicename@hostname" + gssMajStat = gss_import_name(&gssMinStat, + &gssBuffer, + (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, + &gssServiceName); + } + else + { + // The name is of the form "servicename" + gssMajStat = gss_import_name(&gssMinStat, + &gssBuffer, + (gss_OID) GSS_C_NT_USER_NAME, + &gssServiceName); + } + + // Proceed based on the result of the name import operation + if (gssMajStat == GSS_S_COMPLETE) + { + // Establish a context + gss_ctx_id_t gssContext = GSS_C_NO_CONTEXT; + gss_buffer_desc gssSendToken = {0}; + OM_uint32 gssRetFlags; + gssMajStat = gss_init_sec_context(&gssMinStat, + GSS_C_NO_CREDENTIAL, + &gssContext, + gssServiceName, + g_mechOid, + 0, // Flags + 0, + NULL, // no channel bindings + GSS_C_NO_BUFFER, // no token from peer + NULL, // ignore mech type + &gssSendToken, + &gssRetFlags, + NULL); // ignore time rec + + // Proceed based on the result of the gss_init_sec_context operation + if (gssMajStat == GSS_S_COMPLETE + && gssSendToken.length != 0) + { + char *pEncodedToken; + int encodedTokenLen; + + // The security context was initialized, now return it to the caller after base64 encoding it. + retStatus = EncodeData(gssSendToken.value, + gssSendToken.length, + &pEncodedToken, + &encodedTokenLen); + if (CASA_SUCCESS(retStatus)) + { + // Verify that the caller provided a buffer that is big enough + if (encodedTokenLen > *pTokenBufLen) + { + // At least one of the supplied buffers is not big enough + DbgTrace(1, "-AuthTokenIf_GetAuthToken- Insufficient buffer space provided\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_BUFFER_OVERFLOW); + } + else + { + // The buffer provided is large enough, copy the data and return the actual size. + memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen +1); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + + // Return the actual size or the size required + *pTokenBufLen = encodedTokenLen; + + // Free the buffer containing the encoded token + free(pEncodedToken); + } + else + { + DbgTrace(1, "-AuthTokenIf_GetAuthToken- Encoding failed\n", 0); + } + } + else + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Error initing sec context\n", 0); + LogGssStatuses("initializing context", gssMajStat, gssMinStat); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + // Release send token buffer if necessary + if (gssSendToken.length != 0) + gss_release_buffer(&gssMinStat, &gssSendToken); + + + // Free context if necessary + if (gssContext != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&gssMinStat, &gssContext, GSS_C_NO_BUFFER); + + // Release the buffer associated with the service name + gss_release_name(&gssMinStat, &gssServiceName); + } + else + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Error importing service name\n", 0); + LogGssStatuses("importing service name", gssMajStat, gssMinStat); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_OBJECT_NOT_FOUND); + } + +exit: + + DbgTrace(1, "-AuthTokenIf_GetAuthToken- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +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; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/linux/platform.c b/CASA-auth-token/non-java/client/mechanisms/krb5/linux/platform.c new file mode 100644 index 00000000..869b581c --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/linux/platform.c @@ -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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/linux/platform.h b/CASA-auth-token/non-java/client/mechanisms/krb5/linux/platform.h new file mode 100644 index 00000000..72d3c254 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/linux/platform.h @@ -0,0 +1,90 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#define _GNU_SOURCE + +//===[ Include files ]===================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//===[ 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_Krb5Mech %s", printBuff); \ + } \ +} +/*#define DbgTrace(LEVEL, X, Y) { \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + openlog("CASA_Krb5Mech", 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 ]=============================================== + + + +//========================================================================= + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/windows/Krb5Authenticate.conf b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/Krb5Authenticate.conf index df843e9f..76cbd200 100644 --- a/CASA-auth-token/non-java/client/mechanisms/krb5/windows/Krb5Authenticate.conf +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/Krb5Authenticate.conf @@ -1,12 +1,12 @@ -####################################################### -# # -# CASA Authentication Token System configuration file # -# for module: # -# # -# Krb5Authenticate # -# # -####################################################### - -LibraryName \Program Files\novell\casa\lib\krb5mech.dll - - +####################################################### +# # +# CASA Authentication Token System configuration file # +# for module: # +# # +# Krb5Authenticate # +# # +####################################################### + +LibraryName \Program Files\novell\casa\lib\krb5mech.dll + + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/windows/get.c b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/get.c index a3ac6000..82ca30aa 100644 --- a/CASA-auth-token/non-java/client/mechanisms/krb5/windows/get.c +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/get.c @@ -209,7 +209,6 @@ AuthTokenIf_GetAuthToken( // Free the credential handle obtained FreeCredentialsHandle(&hCredentials); - } else { diff --git a/CASA-auth-token/non-java/configure.in b/CASA-auth-token/non-java/configure.in index d3f99a41..08becf0e 100644 --- a/CASA-auth-token/non-java/configure.in +++ b/CASA-auth-token/non-java/configure.in @@ -292,5 +292,7 @@ client/linux/Makefile client/mechanisms/Makefile client/mechanisms/pwd/Makefile client/mechanisms/pwd/linux/Makefile +client/mechanisms/krb5/Makefile +client/mechanisms/krb5/linux/Makefile ])