This branch was created to contain the "native" auth_token components.
This was required because autobuild restrictions are forcing us to build the native components separate from the java components.
This commit is contained in:
		
							
								
								
									
										37
									
								
								CASA-auth-token/native/server/PamSupport/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								CASA-auth-token/native/server/PamSupport/Makefile.am
									
									
									
									
									
										Normal 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 = | ||||
|  | ||||
| EXTRA_DIST = $(CFILES) | ||||
|  | ||||
| .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 | ||||
|  | ||||
							
								
								
									
										80
									
								
								CASA-auth-token/native/server/PamSupport/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								CASA-auth-token/native/server/PamSupport/README
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| /*********************************************************************** | ||||
|  * | ||||
|  *  README for pam_casaauthtok | ||||
|  * | ||||
|  ***********************************************************************/ | ||||
|  | ||||
| INTRODUCTION | ||||
|  | ||||
| pam_casaauthtok is a PAM authentication module which can be configured | ||||
| to validate credentials consisting of CASA Authentication Tokens. | ||||
|  | ||||
| CONFIGURATION | ||||
|  | ||||
| To use pam_casaauthtok as a PAM authentication module for your service, | ||||
| add the following line to the service's PAM configuration file: | ||||
|  | ||||
| auth     required       pam_casaauthtok.so | ||||
|  | ||||
| pam_casaauthtok supports the following input parameters: | ||||
|  | ||||
| U - This parameter tells pam_casaauthtok that it must verify that | ||||
|     the username is set to "CasaPrincipal". If the parameter is not | ||||
|     specified then pam_casaauthtok does not check the username. | ||||
|  | ||||
| CLIENT PROGRAMMING NOTES | ||||
|  | ||||
| Clients must specify the same service name when requesting Authentication | ||||
| Tokens from the CASA Client as the service name specified by the server | ||||
| when opening a PAM handle. | ||||
|  | ||||
| SERVER PROGRAMMING NOTES | ||||
|  | ||||
| Server applications validating credentials containing CASA Authentication | ||||
| tokens can obtain the following information about the authenticated identity: | ||||
|  | ||||
| username - This is obtained by querying PAM using the pam_get_item() call with | ||||
| the item type set to PAM_USER. This can also be obtained by querying PAM | ||||
| using the pam_getenv() call with the variable name set to "IdentityId".  The | ||||
| username is the user's unique id within the authentication realm. When the | ||||
| authentication realm is an LDAP database, the username consists of the user's fdn. | ||||
| Note that PAM applications using pam_casaauthtok need to set username to | ||||
| "CasaPrincipal" when opening a PAM handle and then the variable is updated by | ||||
| pam_casaauthtok during the authentication process with the identity information | ||||
| of the authenticated entity. | ||||
|  | ||||
| Name of the source of identity data (Authentication Realm) - This is obtained | ||||
| by querying PAM using the pam_getenv() call with the variable name set to | ||||
| "IdentityDataSourceName". | ||||
|  | ||||
| URL to the source of identity data - This is obtained | ||||
| by querying PAM using the pam_getenv() call with the variable name set to | ||||
| "IdentityDataSourceUrl". | ||||
|  | ||||
| Attributes of the authenticated identity - The attributes are set as environment | ||||
| variables associated with the PAM handle. The environment variable names match | ||||
| the names of the attributes. The attributes associated with the authenticated | ||||
| identity and expressed as environment variables are configured at the time that | ||||
| the service is enabled for CASA Authentication. | ||||
|  | ||||
| EXAMPLE SERVER APPLICATION | ||||
|  | ||||
| See test/test.c for an example application using PAM to authenticate credentials | ||||
| consisting of CASA Authentication Tokens. | ||||
|  | ||||
| SECURITY CONSIDERATIONS | ||||
|  | ||||
| CASA Authenticatication Tokens when compromised can be used to either impersonate | ||||
| a user or to obtain identity information about the user. Because of this it is | ||||
| important that the tokens be secured by applications making use of them. It is | ||||
| recommended that the tokens be transmitted using SSL. | ||||
|   | ||||
|  | ||||
|  | ||||
|  | ||||
|                  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										13
									
								
								CASA-auth-token/native/server/PamSupport/TODO
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								CASA-auth-token/native/server/PamSupport/TODO
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| /*********************************************************************** | ||||
|  * | ||||
|  *  TODO for pam_casaauthtok | ||||
|  * | ||||
|  ***********************************************************************/ | ||||
|  | ||||
| INTRODUCTION | ||||
|  | ||||
| This file contains a list of the items still outstanding for pam_casaauthtok. | ||||
|  | ||||
| OUTSTANDING ITEMS | ||||
|  | ||||
| None. | ||||
							
								
								
									
										112
									
								
								CASA-auth-token/native/server/PamSupport/linux/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								CASA-auth-token/native/server/PamSupport/linux/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | ||||
| ####################################################################### | ||||
| # | ||||
| #  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 = ../../.. | ||||
|  | ||||
| CASAINCLUDE = ../../../../CASA/include | ||||
|  | ||||
| LIBDIR = $(ROOT)/$(LIB) | ||||
|  | ||||
| # handle Mono secondary dependencies | ||||
| export MONO_PATH := $(MONO_PATH) | ||||
|  | ||||
| PLATFORMINDEPENDENTSOURCEDIR = .. | ||||
| PLATFORMDEPENDENTSOURCEDIR = . | ||||
|  | ||||
| MODULE_NAME = pam_casaauthtok | ||||
| MODULE_EXT = so | ||||
|  | ||||
| CFILES = ../pam_authtoken.c | ||||
|  | ||||
| CSFILES_CSC := | ||||
| INCLUDES = -I. -I$(CASAINCLUDE) -I../../../include | ||||
| RESOURCES = | ||||
| DEFINES = -Wno-format-extra-args -fno-strict-aliasing  | ||||
|  | ||||
| CFLAGS += $(INCLUDES) $(DEFINES) | ||||
| LIBS = -lpthread -lpam -lcasa_s_authtoken | ||||
| LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT) -L$(LIBDIR)/$(TARGET_CFG) | ||||
|  | ||||
| OBJDIR = ./$(TARGET_CFG)/$(LIB) | ||||
| OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o)) | ||||
|  | ||||
| EXTRA_DIST = $(CFILES) | ||||
|  | ||||
| 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: | ||||
| #cd $(TARGET_CFG); rm -rf *.dbg *.exe *.dll *.o *.so; cd ..; rmdir $(OBJDIR) | ||||
| 	rm -rf $(TARGET_CFG) | ||||
|  | ||||
| distclean-local: | ||||
|  | ||||
| maintainer-clean-local: | ||||
| 	rm -f Makefile.in | ||||
|  | ||||
							
								
								
									
										649
									
								
								CASA-auth-token/native/server/PamSupport/pam_authtoken.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										649
									
								
								CASA-auth-token/native/server/PamSupport/pam_authtoken.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,649 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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 <stdarg.h> | ||||
| #include <syslog.h> | ||||
| #include <stdbool.h> | ||||
|  | ||||
| #ifndef LINUX  | ||||
| #include <security/pam_appl.h> | ||||
| #endif | ||||
|  | ||||
| #define PAM_SM_AUTH | ||||
| #define PAM_SM_ACCOUNT | ||||
| #define PAM_SM_PASSWORD | ||||
| #define PAM_SM_SESSION | ||||
|  | ||||
| #include <security/pam_modules.h> | ||||
| #include <security/_pam_macros.h> | ||||
|  | ||||
| #include <casa_s_authtoken.h> | ||||
|  | ||||
| // | ||||
| // Environment variables set by module | ||||
| //  | ||||
| static char CasaIdentityIdEnvVar[] = "IdentityId= "; | ||||
| static char CasaIdentitySourceNameEnvVar[] = "IdentityDataSourceName= "; | ||||
| static char CasaIdentitySourceUrlEnvVar[] = "IdentityDataSourceUrl= "; | ||||
|  | ||||
|  | ||||
| /* ************************************************************************ | ||||
|  * LogError() | ||||
|  * | ||||
|  * Logs error to syslog. | ||||
|  * | ||||
|  * L2 | ||||
|  * ************************************************************************/ | ||||
| static void | ||||
| LogError(char *pFormatStr, ... ) | ||||
| { | ||||
|    va_list  args; | ||||
|  | ||||
|    openlog("pam_casaauthtok", LOG_CONS | LOG_NOWAIT | LOG_ODELAY, LOG_USER); | ||||
|    va_start(args, pFormatStr); | ||||
|    vsyslog(LOG_USER | LOG_INFO, pFormatStr, args); | ||||
|    va_end(args); | ||||
|    closelog(); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ************************************************************************ | ||||
|  * pam_sm_authenticate() | ||||
|  * | ||||
|  * Service provider implementation for pam_authenticate(). | ||||
|  * | ||||
|  * This is a PAM authentication management function. | ||||
|  * | ||||
|  * We are going to validate the credentials using the CASA Authentication | ||||
|  * Token Credential APIs. | ||||
|  * | ||||
|  * L2 | ||||
|  * ************************************************************************/ | ||||
| PAM_EXTERN int | ||||
| pam_sm_authenticate(pam_handle_t *pamh, | ||||
|                     int flags, | ||||
|                     int argc, | ||||
|                     const char **argv) | ||||
| { | ||||
|    int         retStatus = PAM_SUCCESS; | ||||
|    bool        performUsernameCheck = false; | ||||
|    int         i; | ||||
|    char        *pServicename = NULL; | ||||
|    char        *pAuthToken = NULL; | ||||
|  | ||||
|    // Determine if we are supposed to perform the username check | ||||
|    // based on the arguments specified. | ||||
|    for (i = 0; i < argc; i++) | ||||
|    { | ||||
|       if (*(argv[i]) == 'U') | ||||
|       { | ||||
|          // The arguments indicate that we should check the username | ||||
|          performUsernameCheck = true; | ||||
|  | ||||
|          // No need to keep going through the arguments | ||||
|          break; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    // Get the servicename. | ||||
|    if (pam_get_item(pamh, PAM_SERVICE, (void*) &pServicename) == PAM_SUCCESS | ||||
|        && pServicename != NULL) | ||||
|    { | ||||
|       // We got the service name, now check if it is necessary to perform | ||||
|       // the username check. | ||||
|       if (performUsernameCheck) | ||||
|       { | ||||
|          char                 *pUsername; | ||||
|          struct pam_response  *responses = NULL; | ||||
|  | ||||
|          // Obtain the username so that it can be checked. | ||||
|          // . | ||||
|          // Note that we are not calling pam_get_user() because we | ||||
|          // assume that the service has set it before calling PAM_Authenticate. | ||||
|          if (pam_get_item(pamh, PAM_USER, (void*) &pUsername) == PAM_SUCCESS | ||||
|              && pUsername != NULL) | ||||
|          { | ||||
|             // Check if the username matches the name that we are expecting | ||||
|             if (strcmp(pUsername, "CasaPrincipal") != 0) | ||||
|             { | ||||
|                LogError("Un-expected username, %s", pUsername); | ||||
|                retStatus = PAM_USER_UNKNOWN; | ||||
|             } | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             struct pam_conv *pConv; | ||||
|  | ||||
|             // The username has not been set, try to obtain it from the | ||||
|             // application through the use of the conversation function. | ||||
|             if (pam_get_item(pamh, PAM_CONV, (void*) &pConv) == PAM_SUCCESS) | ||||
|             { | ||||
|                struct pam_message   msg; | ||||
|                struct pam_message   *messages = &msg; | ||||
|  | ||||
|                // Obtained the conversation structure, now query the conversation | ||||
|                // function for the username. | ||||
|                msg.msg_style = PAM_PROMPT_ECHO_ON; | ||||
|                if (pConv->conv(1, | ||||
|                                (const struct pam_message **) &messages, | ||||
|                                &responses, | ||||
|                                pConv->appdata_ptr) == PAM_SUCCESS) | ||||
|                { | ||||
|                   // Check if we have a successful response | ||||
|                   if (responses[0].resp_retcode == PAM_SUCCESS | ||||
|                       && responses[0].resp) | ||||
|                   { | ||||
|                      // Check if the username matches the name that we are expecting | ||||
|                      if (strcmp(responses[0].resp, "CasaPrincipal") != 0) | ||||
|                      { | ||||
|                         LogError("Un-expected username, %s", responses[0].resp); | ||||
|                         retStatus = PAM_USER_UNKNOWN; | ||||
|                      } | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      LogError("Username not returned"); | ||||
|                      retStatus = PAM_CRED_INSUFFICIENT; | ||||
|                   } | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   LogError("Conversation function error"); | ||||
|                   retStatus = PAM_AUTH_ERR; | ||||
|                } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                LogError("Unable to obtain conversation structure"); | ||||
|                retStatus = PAM_AUTH_ERR; | ||||
|             } | ||||
|          } | ||||
|  | ||||
|          // Free conversation function response buffers if necessary | ||||
|          if (responses) | ||||
|          { | ||||
|             if (responses[0].resp) | ||||
|                free(responses[0].resp); | ||||
|             free(responses); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       // Proceed with the authentication token check if we have not encountered any | ||||
|       // problems. | ||||
|       if (retStatus == PAM_SUCCESS) | ||||
|       { | ||||
|          struct pam_response  *responses = NULL; | ||||
|  | ||||
|          // Now obtain the authentication token. | ||||
|          if (pam_get_item(pamh, PAM_AUTHTOK, (void*) &pAuthToken) != PAM_SUCCESS | ||||
|              || pAuthToken == NULL) | ||||
|          { | ||||
|             struct pam_conv *pConv; | ||||
|  | ||||
|             // The authentication token has not been set, try to obtain it from the | ||||
|             // application through the use of the conversation function. | ||||
|             if (pam_get_item(pamh, PAM_CONV, (void*) &pConv) == PAM_SUCCESS) | ||||
|             { | ||||
|                struct pam_message   msg; | ||||
|                struct pam_message   *messages = &msg; | ||||
|  | ||||
|                // Obtained the conversation structure, now query the conversation | ||||
|                // function for the authentication token. | ||||
|                msg.msg_style = PAM_PROMPT_ECHO_OFF; | ||||
|                if (pConv->conv(1, | ||||
|                                (const struct pam_message **) &messages, | ||||
|                                &responses, | ||||
|                                pConv->appdata_ptr) == PAM_SUCCESS) | ||||
|                { | ||||
|                   // Check if we have a successful response | ||||
|                   if (responses[0].resp_retcode == PAM_SUCCESS | ||||
|                       && responses[0].resp) | ||||
|                   { | ||||
|                      // Set the authentication token with PAM | ||||
|                      if (pam_set_item(pamh, PAM_AUTHTOK, responses[0].resp) == PAM_SUCCESS) | ||||
|                      { | ||||
|                         // Use the buffer returned by the caller as the authentication token | ||||
|                         pAuthToken = responses[0].resp; | ||||
|                      } | ||||
|                      else | ||||
|                      { | ||||
|                         LogError("Unable to set the authentication token"); | ||||
|                      } | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      LogError("Token not returned"); | ||||
|                   } | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   LogError("Conversation function error"); | ||||
|                } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                LogError("Unable to obtain conversation structure"); | ||||
|             } | ||||
|          } | ||||
|  | ||||
|          // Check if we succeeded at obtaining the authentication token | ||||
|          if (pAuthToken) | ||||
|          { | ||||
|             CasaStatus  casaStatus; | ||||
|             PrincipalIf *pPrincipalIf; | ||||
|  | ||||
|             // Validate the token | ||||
|             casaStatus = ValidateAuthToken(pServicename, | ||||
|                                            pAuthToken, | ||||
|                                            strlen(pAuthToken), | ||||
|                                            &pPrincipalIf); | ||||
|             if (CASA_SUCCESS(casaStatus)) | ||||
|             { | ||||
|                int   buffLen; | ||||
|  | ||||
|                // Assume success | ||||
|                retStatus = PAM_SUCCESS; | ||||
|  | ||||
|                // Associate necessary environment variables with the PAM Handle | ||||
|                buffLen = 0; | ||||
|                casaStatus = pPrincipalIf->getIdentityId(pPrincipalIf, | ||||
|                                                         NULL, | ||||
|                                                         &buffLen); | ||||
|                if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW) | ||||
|                { | ||||
|                   char  *pBuff; | ||||
|  | ||||
|                   // Allocate buffer to contain the Identity Id Environment Variable | ||||
|                   pBuff = malloc(sizeof(CasaIdentityIdEnvVar) + buffLen); | ||||
|                   if (pBuff) | ||||
|                   { | ||||
|                      // Start constructing the environment variable | ||||
|                      memcpy(pBuff, CasaIdentityIdEnvVar, sizeof(CasaIdentityIdEnvVar) - 1); | ||||
|  | ||||
|                      // Read the value into our buffer | ||||
|                      if (CASA_SUCCESS(pPrincipalIf->getIdentityId(pPrincipalIf, | ||||
|                                                                   pBuff + sizeof(CasaIdentityIdEnvVar) - 1, | ||||
|                                                                   &buffLen))) | ||||
|                      { | ||||
|                         // Now set the environment variable | ||||
|                         if (pam_putenv(pamh, pBuff) != PAM_SUCCESS) | ||||
|                         { | ||||
|                            LogError("Unable to set identity id environment variable"); | ||||
|                            retStatus = PAM_SYSTEM_ERR; | ||||
|                         } | ||||
|  | ||||
|                         // Also set the identity id as the username | ||||
|                         if (pam_set_item(pamh, PAM_USER, pBuff + sizeof(CasaIdentityIdEnvVar) - 1) != PAM_SUCCESS) | ||||
|                         { | ||||
|                            LogError("Error setting the username"); | ||||
|                         } | ||||
|                      } | ||||
|                      else | ||||
|                      { | ||||
|                         LogError("Unable to obtain identity id"); | ||||
|                         retStatus = PAM_SYSTEM_ERR; | ||||
|                      } | ||||
|  | ||||
|                      // Free allocated buffer | ||||
|                      free(pBuff); | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      LogError("Buffer allocation failure"); | ||||
|                      retStatus = PAM_BUF_ERR; | ||||
|                   } | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   LogError("Un-expected error obtaining identity id, %08X", casaStatus); | ||||
|                   retStatus = PAM_SYSTEM_ERR; | ||||
|                } | ||||
|  | ||||
|                if (retStatus == PAM_SUCCESS) | ||||
|                { | ||||
|                   buffLen = 0; | ||||
|                   casaStatus = pPrincipalIf->getSourceName(pPrincipalIf, | ||||
|                                                            NULL, | ||||
|                                                            &buffLen); | ||||
|                   if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW) | ||||
|                   { | ||||
|                      char  *pBuff; | ||||
|  | ||||
|                      // Allocate buffer to contain the Identity Source Name Environment Variable | ||||
|                      pBuff = malloc(sizeof(CasaIdentitySourceNameEnvVar) + buffLen); | ||||
|                      if (pBuff) | ||||
|                      { | ||||
|                         // Start constructing the environment variable | ||||
|                         memcpy(pBuff, CasaIdentitySourceNameEnvVar, sizeof(CasaIdentitySourceNameEnvVar) - 1); | ||||
|  | ||||
|                         // Read the value into our buffer | ||||
|                         if (CASA_SUCCESS(pPrincipalIf->getSourceName(pPrincipalIf, | ||||
|                                                                      pBuff + sizeof(CasaIdentitySourceNameEnvVar) - 1, | ||||
|                                                                      &buffLen))) | ||||
|                         { | ||||
|                            // Now set the environment variable | ||||
|                            if (pam_putenv(pamh, pBuff) != PAM_SUCCESS) | ||||
|                            { | ||||
|                               LogError("Unable to set identity source name environment variable"); | ||||
|                               retStatus = PAM_SYSTEM_ERR; | ||||
|                            } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                            LogError("Unable to obtain identity source name"); | ||||
|                            retStatus = PAM_SYSTEM_ERR; | ||||
|                         } | ||||
|  | ||||
|                         // Free allocated buffer | ||||
|                         free(pBuff); | ||||
|                      } | ||||
|                      else | ||||
|                      { | ||||
|                         LogError("Buffer allocation failure"); | ||||
|                         retStatus = PAM_BUF_ERR; | ||||
|                      } | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      LogError("Un-expected error obtaining identity source name, %08X", casaStatus); | ||||
|                      retStatus = PAM_SYSTEM_ERR; | ||||
|                   } | ||||
|                } | ||||
|  | ||||
|                if (retStatus == PAM_SUCCESS) | ||||
|                { | ||||
|                   buffLen = 0; | ||||
|                   casaStatus = pPrincipalIf->getSourceUrl(pPrincipalIf, | ||||
|                                                           NULL, | ||||
|                                                           &buffLen); | ||||
|                   if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW) | ||||
|                   { | ||||
|                      char  *pBuff; | ||||
|  | ||||
|                      // Allocate buffer to contain the Identity Source Url Environment Variable | ||||
|                      pBuff = malloc(sizeof(CasaIdentitySourceUrlEnvVar) + buffLen); | ||||
|                      if (pBuff) | ||||
|                      { | ||||
|                         // Start constructing the environment variable | ||||
|                         memcpy(pBuff, CasaIdentitySourceUrlEnvVar, sizeof(CasaIdentitySourceUrlEnvVar) - 1); | ||||
|  | ||||
|                         // Read the value into our buffer | ||||
|                         if (CASA_SUCCESS(pPrincipalIf->getSourceUrl(pPrincipalIf, | ||||
|                                                                     pBuff + sizeof(CasaIdentitySourceUrlEnvVar) - 1, | ||||
|                                                                     &buffLen))) | ||||
|                         { | ||||
|                            // Now set the environment variable | ||||
|                            if (pam_putenv(pamh, pBuff) != PAM_SUCCESS) | ||||
|                            { | ||||
|                               LogError("Unable to set identity source url environment variable"); | ||||
|                               retStatus = PAM_SYSTEM_ERR; | ||||
|                            } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                            LogError("Unable to obtain identity source url"); | ||||
|                            retStatus = PAM_SYSTEM_ERR; | ||||
|                         } | ||||
|  | ||||
|                         // Free allocated buffer | ||||
|                         free(pBuff); | ||||
|                      } | ||||
|                      else | ||||
|                      { | ||||
|                         LogError("Buffer allocation failure"); | ||||
|                         retStatus = PAM_BUF_ERR; | ||||
|                      } | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      LogError("Un-expected error obtaining identity source url, %08X", casaStatus); | ||||
|                      retStatus = PAM_SYSTEM_ERR; | ||||
|                   } | ||||
|                } | ||||
|  | ||||
|                if (retStatus == PAM_SUCCESS) | ||||
|                { | ||||
|                   char  *pBuff; | ||||
|                   int   enumHandle = 0; | ||||
|                   int   buff2Len; | ||||
|  | ||||
|                   while (retStatus == PAM_SUCCESS) | ||||
|                   { | ||||
|                      // Get attribute lengths | ||||
|                      buffLen = buff2Len = 0; | ||||
|                      casaStatus = pPrincipalIf->attributeEnumerate(pPrincipalIf, | ||||
|                                                                    &enumHandle, | ||||
|                                                                    NULL, | ||||
|                                                                    &buffLen, | ||||
|                                                                    NULL, | ||||
|                                                                    &buff2Len); | ||||
|                      if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW) | ||||
|                      { | ||||
|                         // Allocate buffer to contain the Identity attribute Environment Variable | ||||
|                         pBuff = malloc(buffLen + 2 + buff2Len); | ||||
|                         if (pBuff) | ||||
|                         { | ||||
|                            // Read the attribute into our buffer | ||||
|                            if (CASA_SUCCESS(pPrincipalIf->attributeEnumerate(pPrincipalIf, | ||||
|                                                                              &enumHandle, | ||||
|                                                                              pBuff, | ||||
|                                                                              &buffLen, | ||||
|                                                                              pBuff + buffLen + 1, // This includes the NULL terminator | ||||
|                                                                              &buff2Len))) | ||||
|                            { | ||||
|                               // Finish constructing the environment variable string | ||||
|                               *(pBuff + buffLen - 1) = '='; | ||||
|                               *(pBuff + buffLen) = ' '; | ||||
|  | ||||
|                               // Now set the environment variable | ||||
|                               if (pam_putenv(pamh, pBuff) != PAM_SUCCESS) | ||||
|                               { | ||||
|                                  LogError("Unable to set identity attribute environment variable"); | ||||
|                                  retStatus = PAM_SYSTEM_ERR; | ||||
|                               } | ||||
|                            } | ||||
|                            else | ||||
|                            { | ||||
|                               LogError("Unable to obtain identity attribute"); | ||||
|                               retStatus = PAM_SYSTEM_ERR; | ||||
|                            } | ||||
|  | ||||
|                            // Free allocated buffer | ||||
|                            free(pBuff); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                            LogError("Buffer allocation failure"); | ||||
|                            retStatus = PAM_BUF_ERR; | ||||
|                         } | ||||
|                      } | ||||
|                      else | ||||
|                      { | ||||
|                         // Check if we are done going through the attributes | ||||
|                         if (CasaStatusCode(casaStatus) == CASA_STATUS_NO_MORE_ENTRIES) | ||||
|                         { | ||||
|                            // Done | ||||
|                            break; | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                            LogError("Un-expected error during attribute enumeration, %08X", casaStatus); | ||||
|                            retStatus = PAM_SYSTEM_ERR; | ||||
|                         } | ||||
|                      } | ||||
|                   } | ||||
|                } | ||||
|  | ||||
|                // Release the principal interface instance | ||||
|                pPrincipalIf->releaseReference(pPrincipalIf); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                LogError("Service %s failed to authenticate with status = %08X", pServicename, casaStatus); | ||||
|                retStatus = PAM_AUTH_ERR; | ||||
|             } | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             LogError("Unable to obtain authentication token"); | ||||
|             retStatus = PAM_CRED_INSUFFICIENT; | ||||
|          } | ||||
|  | ||||
|          // Free conversation function response buffers if necessary | ||||
|          if (responses) | ||||
|          { | ||||
|             if (responses[0].resp) | ||||
|                free(responses[0].resp); | ||||
|             free(responses); | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       LogError("Unable to obtain servicename"); | ||||
|       retStatus = PAM_SYSTEM_ERR; | ||||
|    } | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ************************************************************************ | ||||
|  * pam_sm_setcred() | ||||
|  * | ||||
|  * Service provider implementation for pam_setcred(). | ||||
|  * | ||||
|  * This is a PAM authentication management function. | ||||
|  * | ||||
|  * This function is here just for completedness and to protect against | ||||
|  * PAM misconfiguration. | ||||
|  * | ||||
|  * ************************************************************************/ | ||||
| PAM_EXTERN int | ||||
| pam_sm_setcred(pam_handle_t *pamh, | ||||
|                int flags, | ||||
|                int argc, | ||||
|                const char **argv) | ||||
| { | ||||
|    return PAM_SUCCESS; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ************************************************************************ | ||||
|  * pam_sm_acct_mgmt() | ||||
|  * | ||||
|  * Service provider implementation for pam_acct_mgmt(). | ||||
|  * | ||||
|  * This is a PAM account management function. | ||||
|  * | ||||
|  * This function is here just for completedness and to protect against | ||||
|  * PAM misconfiguration. | ||||
|  * | ||||
|  * ************************************************************************/ | ||||
| PAM_EXTERN int | ||||
| pam_sm_acct_mgmt(pam_handle_t *pamh, | ||||
|                  int flags, | ||||
|                  int argc, | ||||
|                  const char **argv) | ||||
| { | ||||
|    return PAM_SUCCESS; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ************************************************************************ | ||||
|  * pam_sm_chauthtok() | ||||
|  * | ||||
|  * Service provider implementation for pam_chauthtok(). | ||||
|  * | ||||
|  * This is a PAM password management function. | ||||
|  * | ||||
|  * This function is here just for completedness and to protect against | ||||
|  * PAM misconfiguration. | ||||
|  * | ||||
|  * ************************************************************************/ | ||||
| PAM_EXTERN int | ||||
| pam_sm_chauthtok(pam_handle_t *pamh, | ||||
|                  int flags, | ||||
|                  int argc, | ||||
|                  const char **argv) | ||||
| { | ||||
|    return PAM_SUCCESS; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ************************************************************************ | ||||
|  * pam_sm_open_session() | ||||
|  * | ||||
|  * Service provider implementation for pam_open_session(). | ||||
|  * | ||||
|  * This is a PAM session management function. | ||||
|  * | ||||
|  * This function is here just for completedness and to protect against | ||||
|  * PAM misconfiguration. | ||||
|  * | ||||
|  * ************************************************************************/ | ||||
| PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, | ||||
|                                    int flags, | ||||
|                                    int argc, | ||||
|                                    const char **argv) | ||||
| { | ||||
|    return PAM_SUCCESS; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ************************************************************************ | ||||
|  * pam_sm_close_session() | ||||
|  * | ||||
|  * Service provider implementation for pam_close_session(). | ||||
|  * | ||||
|  * This is a PAM session management function. | ||||
|  * | ||||
|  * This function is here just for completedness and to protect against | ||||
|  * PAM misconfiguration. | ||||
|  * | ||||
|  * ************************************************************************/ | ||||
| PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, | ||||
|                                     int flags, | ||||
|                                     int argc, | ||||
|                                     const char **argv) | ||||
| { | ||||
|    return PAM_SUCCESS; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* static module data */ | ||||
| #ifdef PAM_STATIC | ||||
| struct pam_module _pam_casa_authtoken_modstruct = { | ||||
|    "pam_casa_authtoken", | ||||
|    pam_sm_authenticate, | ||||
|    pam_sm_setcred, | ||||
|    pam_sm_acct_mgmt, | ||||
|    pam_sm_chauthtok, | ||||
|    pam_sm_open_session, | ||||
|    pam_sm_close_session | ||||
| }; | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										32
									
								
								CASA-auth-token/native/server/PamSupport/test/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								CASA-auth-token/native/server/PamSupport/test/README
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| /*********************************************************************** | ||||
|  * | ||||
|  *  README for pamTest | ||||
|  * | ||||
|  ***********************************************************************/ | ||||
|  | ||||
| INTRODUCTION | ||||
|  | ||||
| pamTest is a PAM application which tests using CASA authentication tokens | ||||
| for authentication. | ||||
|  | ||||
| CONFIGURATION | ||||
|  | ||||
| Place a copy of file testservice in the /etc/pam.d folder. | ||||
|  | ||||
| BUILDING APPLICATION | ||||
|  | ||||
| Execute script: make.sh. | ||||
|  | ||||
| RUNNING APPLICATION | ||||
|  | ||||
| Execute the following command: ./pamTest -s testService | ||||
|   | ||||
|  | ||||
|  | ||||
|  | ||||
|                  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										2
									
								
								CASA-auth-token/native/server/PamSupport/test/make.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										2
									
								
								CASA-auth-token/native/server/PamSupport/test/make.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| #!/bin/bash | ||||
| gcc -o pamTest test.c -g -I"../../.." -I"../../../../include" -DN_PLAT_UNIX -L"../../../lib/Release" -lpam | ||||
							
								
								
									
										520
									
								
								CASA-auth-token/native/server/PamSupport/test/test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										520
									
								
								CASA-auth-token/native/server/PamSupport/test/test.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,520 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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 <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <stdbool.h> | ||||
| #include <getopt.h> | ||||
| #include <errno.h> | ||||
| #include <security/pam_appl.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| #include <netdb.h> | ||||
|  | ||||
| //===[ Type definitions ]================================================== | ||||
|  | ||||
| typedef struct _AppUserData | ||||
| { | ||||
|    char  *pUserName; | ||||
|    char  *pAuthToken; | ||||
|  | ||||
| } AppUserData, *PAppUserData; | ||||
|  | ||||
| // | ||||
| // DbgTrace macro define | ||||
| // | ||||
| #define DbgTrace(LEVEL, X, Y) {                          \ | ||||
|    if (LEVEL == 0)                                       \ | ||||
|       printf(X, Y);                                      \ | ||||
|    else if (DebugLevel >= LEVEL)                         \ | ||||
|          printf(X, Y);                                   \ | ||||
| } | ||||
|  | ||||
| // | ||||
| // Socket Mapping definitions | ||||
| // | ||||
| #define INVALID_SOCKET -1 | ||||
| #define SOCKET_ERROR -1 | ||||
| #define LINGER struct linger | ||||
| #define SOCKADDR_IN struct sockaddr_in | ||||
| #define closesocket close | ||||
|  | ||||
|  | ||||
| //===[ Function prototypes ]=============================================== | ||||
|  | ||||
| //===[ Global variables ]================================================== | ||||
|  | ||||
| // Usage string | ||||
| char  usage[] = "\nPamTest: usage: -s serviceName [-D DebugLevel]\n"; | ||||
|  | ||||
| // Debug Level | ||||
| int   DebugLevel = 3; | ||||
|  | ||||
| char  *pServiceName = NULL; | ||||
|  | ||||
| //++======================================================================= | ||||
| int | ||||
| Converse(int num_msg, | ||||
|          const struct pam_message **msg, | ||||
| 		   struct pam_response **resp, | ||||
|          void *appdata_ptr) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| //  Environment: | ||||
| // | ||||
| //=======================================================================-- | ||||
| { | ||||
|    int                  retStatus = PAM_SUCCESS; | ||||
|    int                  replies = 0; | ||||
|    struct pam_response  *reply = NULL; | ||||
|    AppUserData          *pAppUserData = (PAppUserData) appdata_ptr; | ||||
|  | ||||
|    // Initialize output parameters | ||||
|    *resp = NULL; | ||||
|  | ||||
|    // Check input parameters | ||||
|    if (num_msg <= 0 || appdata_ptr == NULL) | ||||
|       return PAM_CONV_ERR; | ||||
|  | ||||
|    // Allocate enough space for the replies | ||||
|    reply = malloc(sizeof(struct pam_response) * num_msg); | ||||
|    if (!reply) | ||||
|       return PAM_CONV_ERR; | ||||
|  | ||||
|    // Zero the reply buffer | ||||
|    memset(reply, 0, sizeof(struct pam_response) * num_msg); | ||||
|  | ||||
|    for (replies = 0; | ||||
|         replies < num_msg && retStatus == PAM_SUCCESS; | ||||
|         replies++) | ||||
|    { | ||||
|       switch (msg[replies]->msg_style) | ||||
|       { | ||||
|          case PAM_PROMPT_ECHO_ON: | ||||
|  | ||||
|             // The caller wants the username | ||||
|             reply[replies].resp_retcode = PAM_SUCCESS; | ||||
|             reply[replies].resp = malloc(strlen(pAppUserData->pUserName) + 1); | ||||
|             if (reply[replies].resp) | ||||
|                strcpy(reply[replies].resp, pAppUserData->pUserName); | ||||
|             else | ||||
|             { | ||||
|                DbgTrace(0, "Converse- Buffer allocation failure\n", 0); | ||||
|                retStatus = PAM_CONV_ERR; | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|          case PAM_PROMPT_ECHO_OFF: | ||||
|  | ||||
|             // The caller wants the authentication token | ||||
|             reply[replies].resp_retcode = PAM_SUCCESS; | ||||
|             reply[replies].resp = malloc(strlen(pAppUserData->pAuthToken) + 1); | ||||
|             if (reply[replies].resp) | ||||
|             { | ||||
|                strcpy(reply[replies].resp, pAppUserData->pAuthToken); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                DbgTrace(0, "Converse- Buffer allocation failure\n", 0); | ||||
|                retStatus = PAM_CONV_ERR; | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|          case PAM_TEXT_INFO: | ||||
|          case PAM_ERROR_MSG: | ||||
|  | ||||
|             // Just return success | ||||
|             reply[replies].resp_retcode = PAM_SUCCESS; | ||||
|             reply[replies].resp = NULL; | ||||
|             break; | ||||
|  | ||||
|          default: | ||||
|  | ||||
|             // Un-expected | ||||
|             retStatus = PAM_CONV_ERR; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    // Proceed based on the status | ||||
|    if (retStatus == PAM_SUCCESS) | ||||
|    { | ||||
|       *resp = reply; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       // Free buffers allocated for the reply | ||||
|       for (replies = 0; | ||||
|            replies < num_msg && retStatus == PAM_SUCCESS; | ||||
|            replies++) | ||||
|       { | ||||
|          if (reply[replies].resp != NULL) | ||||
|             free(reply[replies].resp); | ||||
|       } | ||||
|       free(reply); | ||||
|    } | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| int | ||||
| ReadLineIntoBuffer(int connSock, char *pBuffer) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| //  Environment: | ||||
| // | ||||
| //=======================================================================-- | ||||
| { | ||||
|    int               i = 0; | ||||
|    char              c; | ||||
|    int               bytesReceived = 0; | ||||
|  | ||||
|    DbgTrace(2, "ReadLineIntoBuffer- Start\n", 0); | ||||
|  | ||||
|    // Receive the line | ||||
|    while ((bytesReceived = recv(connSock, &c, 1, 0)) == 1) | ||||
|    { | ||||
|       if (c == '\n') | ||||
|          break; | ||||
|       else | ||||
|       { | ||||
|          pBuffer[i] = c; | ||||
|          i ++; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    // Check for a socket error | ||||
|    if (bytesReceived == 0) | ||||
|    { | ||||
|       DbgTrace(0, "ReadLineIntoBuffer- Socket error\n", 0); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(2, "ReadLineIntoBuffer- End, lineLength = %d\n", i); | ||||
|  | ||||
|    return i; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| void | ||||
| ProcessConnection(int connSock) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| //  Environment: | ||||
| // | ||||
| //=======================================================================-- | ||||
| { | ||||
|    char              userName[] = "CasaPrincipal"; | ||||
|    char              token[4096] = {0}; | ||||
|    char              helloString[100] = {0}; | ||||
|    AppUserData       appUserData = {userName, token}; | ||||
|    struct pam_conv   conv = {Converse, &appUserData}; | ||||
|    pam_handle_t      *pamh; | ||||
|    int               pam_status; | ||||
|  | ||||
|    DbgTrace(1, "ProcessConnection- Start\n", 0); | ||||
|  | ||||
|    // We have received a connection | ||||
|    printf("\n\nConnection received\n"); | ||||
|  | ||||
|    // Receive the token | ||||
|    if (ReadLineIntoBuffer(connSock, token) == 0) | ||||
|    { | ||||
|       DbgTrace(0, "ProcessConnection- Error receiving token\n", 0); | ||||
|       goto exit; | ||||
|    } | ||||
|    //printf("Token received = %s\n", token); | ||||
|  | ||||
|    // We obtained authentication token credentials to authenticate | ||||
|    // to the service, now verify the credentials using PAM_Authenticate. | ||||
|    // | ||||
|    // Open a PAM Handle | ||||
|    pam_status = pam_start(pServiceName, userName, &conv, &pamh); | ||||
|    if (pam_status == PAM_SUCCESS) | ||||
|    { | ||||
|       // Now authenticate the user | ||||
|       pam_status = pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK); | ||||
|       if (pam_status == PAM_SUCCESS) | ||||
|       { | ||||
|          char  **pam_envlist; | ||||
|          char  **pam_env; | ||||
|          char  *pUsername; | ||||
|  | ||||
|          DbgTrace(1, "ProcessConnection- pam_authenticate success\n", 0); | ||||
|          printf("Authentication succeeded\n"); | ||||
|          printf("The DUDE is cool\n"); | ||||
|  | ||||
|          // Get the identity information about the DUDE | ||||
|  | ||||
|          // Notice that the username may have been updated during the authentication process | ||||
|          if (pam_get_item(pamh, PAM_USER, (void*) &pUsername) == PAM_SUCCESS | ||||
|              && pUsername != NULL) | ||||
|          { | ||||
|             printf("The username of the authenticated identity is %s\n", pUsername); | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             DbgTrace(0, "ProcessConnection- pam_get_item did not return the username\n", 0); | ||||
|          } | ||||
|  | ||||
|          // Show identity information obtained during the authentication process and maintained | ||||
|          // as PAM environment variables. | ||||
|          pam_envlist = pam_getenvlist(pamh); | ||||
|          if (pam_envlist != NULL) | ||||
|          { | ||||
|             // Display the environment variables and free the memory associated | ||||
|             // with them. | ||||
|             for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env) | ||||
|             { | ||||
|                printf("%s\n", *pam_env); | ||||
|                free(*pam_env); | ||||
|             } | ||||
|             free(pam_envlist); | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             DbgTrace(0, "ProcessConnection- pam_getenvlist did not return any data\n", 0); | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          DbgTrace(0, "ProcessConnection- pam_authenticate failure, error = %s\n", pam_strerror(pamh, pam_status)); | ||||
|          printf("The DUDE is a fake\n"); | ||||
|       } | ||||
|  | ||||
|       // Close the PAM Handle | ||||
|       pam_end(pamh, pam_status | PAM_DATA_SILENT); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(0, "ProcessConnection- pam_start failure, status = %08X\n", pam_status); | ||||
|    } | ||||
|  | ||||
| exit: | ||||
|  | ||||
|    DbgTrace(1, "ProcessConnection- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| void | ||||
| ExecuteTests(void) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| //  Environment: | ||||
| // | ||||
| //=======================================================================-- | ||||
| { | ||||
|    int                  connSock; | ||||
|    int                  listenSock; | ||||
|    struct sockaddr_in   localAddr = {0}; | ||||
|    struct sockaddr_in   boundAddr = {0}; | ||||
|    struct sockaddr_in   remoteAddr = {0}; | ||||
|    struct linger        linger_opt = {1, 15}; | ||||
|    int                  on = 1; | ||||
|    socklen_t            addrLen = sizeof(struct sockaddr_in); | ||||
|  | ||||
|    DbgTrace(1, "ExecuteTests- Start\n", 0); | ||||
|  | ||||
|    // Open listen socket | ||||
|    listenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||||
|    if (listenSock != INVALID_SOCKET) | ||||
|    { | ||||
|       // Setup the local address structure | ||||
|       localAddr.sin_family = AF_INET; | ||||
|       localAddr.sin_addr.s_addr = htonl(INADDR_ANY); | ||||
|  | ||||
|       // Set the SO_REUSEADDR option on the socket to avoid | ||||
|       // problems in case of a re-start. | ||||
|       setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); | ||||
|  | ||||
|       // Bind socket | ||||
|       if (!bind(listenSock, (const struct sockaddr*) &localAddr, sizeof(struct sockaddr_in))) | ||||
|       { | ||||
|          // Display the local address information | ||||
|          if (getsockname(listenSock, | ||||
|                          (struct sockaddr*) &boundAddr, | ||||
|                          &addrLen) != SOCKET_ERROR) | ||||
|          { | ||||
|             printf("Listen port = %d\n", boundAddr.sin_port); | ||||
|  | ||||
|             // Now start linstening for connections | ||||
|             if (listen(listenSock, SOMAXCONN) != SOCKET_ERROR) | ||||
|             { | ||||
|                // Loop accepting connections | ||||
|                while (1) | ||||
|                { | ||||
|                   addrLen = sizeof(remoteAddr); | ||||
|                   connSock = accept(listenSock, | ||||
|                                 (struct sockaddr*) &remoteAddr, | ||||
|                                 &addrLen); | ||||
|                   if (connSock != INVALID_SOCKET) | ||||
|                   { | ||||
|                      ProcessConnection(connSock); | ||||
|  | ||||
|                      // Close the connection socket | ||||
|                      closesocket(connSock); | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      DbgTrace(0, "ExecuteTests- - Accept failed, error = %08X\n", errno); | ||||
|                      break; | ||||
|                   } | ||||
|                } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                DbgTrace(0, "ExecuteTests- Unable to start listening, error = %d", errno); | ||||
|             } | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             DbgTrace(0, "ExecuteTests- Unable to obtain local address information, error = %d", errno); | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          DbgTrace(0, "ExecuteTests- Unable to bind socket, error = %d", errno); | ||||
|       } | ||||
|  | ||||
|       // Close the listen socket | ||||
|       closesocket(listenSock); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(0, "ExecuteTests- Unable to open socket, error = %d\n", errno); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "ExecuteTests- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| int | ||||
| main( | ||||
|    int argc, | ||||
|    char* argv[]) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    int         optionsSpecified = 0; | ||||
|    bool        doneScanning = false; | ||||
|    bool        invalidOption = false; | ||||
|    int         option; | ||||
|  | ||||
|    printf("**** server auth_token test ****\n"); | ||||
|  | ||||
|    // Scan through the options specified | ||||
|    while (!doneScanning) | ||||
|    { | ||||
|       opterr = 0; | ||||
|       option = getopt(argc, argv, "s:D:"); | ||||
|  | ||||
|       // Proceed based on the result | ||||
|       switch (option) | ||||
|       { | ||||
|          case 'D': | ||||
|             // Set the debug level | ||||
|             printf("DebugLevel = %s\n", optarg); | ||||
|             DebugLevel = atoi(optarg); | ||||
|             optionsSpecified++; | ||||
|             break; | ||||
|  | ||||
|          case 's': | ||||
|             // Set the service name | ||||
|             printf("Service name = %s\n", optarg); | ||||
|             pServiceName = optarg; | ||||
|             optionsSpecified++; | ||||
|             break; | ||||
|  | ||||
|          case '?': | ||||
|             // Invalid option detected | ||||
|             doneScanning = true; | ||||
|             invalidOption = true; | ||||
|             break; | ||||
|  | ||||
|          default: | ||||
|             // Done scanning | ||||
|             doneScanning = true; | ||||
|             break; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    // Do some sanity checking | ||||
|    if (!invalidOption | ||||
|        && pServiceName != NULL) | ||||
|    { | ||||
|       ExecuteTests(); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       // Invalid option detected | ||||
|       printf(usage, argv[0]); | ||||
|    } | ||||
|  | ||||
|    return 0; | ||||
|  | ||||
| }  /*-- main() --*/ | ||||
|  | ||||
| @@ -0,0 +1,6 @@ | ||||
| #%PAM-1.0 | ||||
| auth	 required	pam_casaauthtok.so U | ||||
| account  required	pam_casaauthtok.so | ||||
| password required	pam_casaauthtok.so | ||||
| session  required       pam_casaauthtok.so | ||||
|  | ||||
		Reference in New Issue
	
	Block a user