From 32a045af7ce9e86dda0c4b59552fd3b297d0e8af Mon Sep 17 00:00:00 2001 From: Jim Norman Date: Thu, 28 Feb 2008 18:34:43 +0000 Subject: [PATCH] Added code to call card selector for mapped secrets (WIP) --- CASA/include/cardselector.h | 28 ++ CASA/micasadk/cardselector.c | 481 ++++++++++++++++++++++++++++++++ CASA/micasadk/linux/Makefile.am | 1 + CASA/micasadk/linux/objs.lux | 1 + CASA/micasadk/sscs_ndk.c | 76 ++++- 5 files changed, 586 insertions(+), 1 deletion(-) create mode 100644 CASA/include/cardselector.h create mode 100644 CASA/micasadk/cardselector.c diff --git a/CASA/include/cardselector.h b/CASA/include/cardselector.h new file mode 100644 index 00000000..7e72d5b3 --- /dev/null +++ b/CASA/include/cardselector.h @@ -0,0 +1,28 @@ +/*********************************************************************** + * + * Copyright (C) 2005-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. + * + ***********************************************************************/ + +#include "micasa_types.h" +#include "micasa_mgmd.h" + +int launchSelector( void *secretHandle, + SSCS_BASIC_CREDENTIAL *basicCred); + diff --git a/CASA/micasadk/cardselector.c b/CASA/micasadk/cardselector.c new file mode 100644 index 00000000..23f27fd2 --- /dev/null +++ b/CASA/micasadk/cardselector.c @@ -0,0 +1,481 @@ +/*********************************************************************** + * + * Copyright (C) 2005-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. + * + ***********************************************************************/ + +// This code finds and launches the card selector with the mapped claims + +#include +#include +#include +#include +#include +#include + +#include "micasa_types.h" +#include "micasa.h" +#include "sscs_lldefs.h" + +#include "sscs_cache.h" +#include "sscs_utf8.h" +#include "micasa.h" + +#include "cardselector.h" + + +#define DM_TEST_ARG_STR "--test" +#define DM_GET_TOKEN_ARG_STR "--gettoken " +#define DM_TRUSTED_ISSUER_URIS_ARG_STR "--issuers" +#define DM_RECIPIENT_ARG_STR "--recipient" +#define DM_REQUIRED_CLAIMS_ARG_STR "--reqclaims" +#define DM_OPTIONAL_CLAIMS_ARG_STR "--optclaims" +#define DM_TOKEN_TYPE_ARG_STR "--tokentype=\"urn:oasis:names:tc:SAML:1.0:assertion\"" +#define DM_PRIVACY_POLICY_FILE_ARG_STR "--privfile" +#define DM_CERT_FILE_ARG_STR "--certfile" +#define DM_TOKEN_OUTPUT_FILE_ARG_STR "--tokenfile" +#define DM_NON_SECURE_DESKTOP_ARG_STR "--nonsecure " +#define DM_VERSION_ARG_STR "--version" +#define DM_ISSUER_POLICY_ARG_STR "--issuerpolicy" +#define DM_UID_ARG_STR "--setuid" +#define DM_MAPTOSIMPLE_ARG_STR "--maptosimple" + +#define DM_TOKEN_TYPE "urn:oasis:names:tc:SAML:1.0:assertion"; + +#define MAXARGS 20 +#define MAXCLAIMS 20 + +const char *dmPaths[] = { "/usr/local/lib/digitalme/bin/digitalme", + "/usr/lib/digitalme/bin/digitalme", + //sUserhome + "/Desktop/DigitalMe.app.Contents/MacOS/DigitalMe", + "/Applications/DigitalMe.app/Contents/MacOS/DigitalMe", + "/Applications/Utilities/DigitalMe.app/Contents/MacOS" + //sUserhome + "/dev/iss/ui/cocoa/xcode/DigitalMe/build/Release/DigitalMe.app/Contents/MacOS/DigitalMe" + }; + + +/**************************************************************************** +Desc: +****************************************************************************/ +int32_t f_exec( const char * pszExe, + const char * argList[], + const char * pStdOut, + long * piExitCode) +{ + + int32_t rc = 0; //NE_FTK_OK; + int pipeDesc[ 2]; + int iChildProcId = -1; + int iChildStatus; + int iOption; + + // Initializations + + pipeDesc[ 0] = -1; + pipeDesc[ 1] = -1; + + if( piExitCode) + { + *piExitCode = -1; + } + + // Allocate a pipe to facilitate communication between this (the parent) + // process and the child we are going to spawn + + if( pipe( pipeDesc) == -1) + { + rc = -1; //RC_SET( NE_FTK_FAILURE); + goto Exit; + } + + // Fork + + if( (iChildProcId = fork()) == -1) + { + rc = -1; //C_SET( NE_FTK_FAILURE); + goto Exit; + } + + // Parent process + + if( iChildProcId) + { + unsigned short ucByte; + + // Close the write end of the pipe + + close( pipeDesc[ 1]); + pipeDesc[ 1] = -1; + + iOption = 1; + ioctl( pipeDesc[0], FIONBIO, &iOption); + + if( waitpid( iChildProcId, &iChildStatus, 0) == -1) + { + rc = -1; //RC_SET( NE_FTK_FAILURE); + goto Exit; + } + + if( piExitCode) + { + *piExitCode = WEXITSTATUS( iChildStatus); + } + + // Read stdin from the child process + + while( read( pipeDesc[ 0], &ucByte, 1) > 0) + { + if( pStdOut) + { + strcat(pStdOut, ucByte); + // if( RC_BAD( rc = pStdOut->appendByte( ucByte))) + // { + // goto Exit; + // } + } + } + + if( pStdOut) + { + strcat(pStdOut, 0); + // if( RC_BAD( rc = pStdOut->appendByte( 0))) + // { + // goto Exit; + // } + } + + // Close the pipe + + close( pipeDesc[ 0]); + pipeDesc[ 0] = -1; + } + else + { + // Close the input end of the pipe + + close( pipeDesc[ 0]); + pipeDesc[ 0] = -1; + + // Re-direct stdout + + if( dup2( pipeDesc[ 1], 1) == -1) + { + rc = -1; //RC_SET( NE_FTK_FAILURE); + goto Exit; + } + + // close( 0); + // close( 2); + + // Overlay the new executable + + if( execvp( pszExe, argList) != 0) + { + rc = -1; //RC_SET( NE_FTK_FAILURE); + goto Exit; + } + } + +Exit: + + if( pipeDesc[ 0] != -1) + { + close( pipeDesc[ 0]); + } + + if( pipeDesc[ 1] != -1) + { + close( pipeDesc[ 1]); + } + + return( rc); +} + + +/**************************************************************************** +Desc: +****************************************************************************/ +int findDigitalMe(int * index) +{ + + int i = 0; + + // Locate digitalme + { + for (i=0; i<4; i++) + { + printf("Checking: %s :", dmPaths[i]); + + if( access( dmPaths[i], F_OK) == -1) + { + printf("NO\r\n"); + } + else + { + index = i; + return 0; + } + } + } + + return -1; + +} + + +/**************************************************************************** +Desc: +****************************************************************************/ +int getLine(char *line, int max, FILE *fp) +{ + if (line == NULL) + { + printf("getLine: no buffer\r\n"); + return 0; + } + + if (fgets(line, max, fp) == NULL) + return 0; + else + return strlen(line); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +int launchSelector(void *secretHandle, + SSCS_BASIC_CREDENTIAL *basicCred) + +{ + int32_t rcode = 0; + int32_t userFound = 0, passFound = 0; + SS_UTF8_T *pKey = NULL; + uint8_t *pValue = NULL; + uint32_t unkLen = 0; + uint32_t kLen = 0; + uint32_t vLen = 0; + + int32_t argCount = 0; + void *pArgs[MAXARGS] = {0}; + + int32_t claimCount = 0; + void *pKeys[MAXCLAIMS] = {0}; + void *pClaims[MAXCLAIMS] = {0}; + int32_t claimStrLen = 0; + void *pClaimsStr = 0; + + void *pTempPtr; + int i = 0; + + FILE * tokenfile; + + char filename[L_tmpnam+1]; + char *ptr; + void *pFileName = 0; + + const char line[256]; + + char claimURI[256]; + char claimvalue[256]; + + int indexToDigitalMeApp = 0; + + if (findDigitalMe(&indexToDigitalMeApp) == 0) + { + // Get a temp name for the token file + ptr = tmpnam(filename); + + printf("launchSelector entered\r\n"); + + if( secretHandle == NULL ) + { + printf("Handle null\r\n"); + return -1; + } + + if( !basicCred) + { + printf("Cred is null\r\n"); + return -1; + } + + if((pValue = (uint8_t *)malloc(NSSCS_MAX_SECRET_BUF_LEN)) == NULL) + { + return NSSCS_E_INVALID_SECRET_ID; + } + + if((pKey = (SS_UTF8_T *)malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) + { + free(pValue); + return NSSCS_E_INVALID_SECRET_ID; + } + + // read the mapped pClaims + // enumerate this list looking for username and password + if(!(rcode = miCASA_GetNextSHSEntry(1, secretHandle, &kLen, pKey, &vLen, pValue))) + { + do + { + if(kLen == 0) + { + break; + } + + // Save of key anc claim mapping + if (argCount < MAXCLAIMS) + { + pTempPtr = malloc(sscs_strlen(pValue)); + sscs_strncpy(pTempPtr, pKey, sscs_strlen(pKey)); + pKeys[claimCount] = pTempPtr; + + printf("URI: %s\r\n", pValue); + pTempPtr = malloc(sscs_strlen(pValue)); + sscs_strncpy(pTempPtr, pValue, sscs_strlen(pValue)); + pClaims[claimCount++] = pTempPtr; + claimStrLen += sscs_strlen(pValue); + } + + // clear the buffers + memset(pKey, 0, NSSCS_MAX_SECRET_ID_LEN); + memset(pValue, 0, NSSCS_MAX_SECRET_BUF_LEN); + + rcode = miCASA_GetNextSHSEntry(0, secretHandle, &kLen, pKey, &vLen, pValue); + } + while(rcode == NSSCS_SUCCESS); + } + + printf("Launch selector\r\n"); + + // Set up args + pArgs[argCount++] = dmPaths[indexToDigitalMeApp]; + pArgs[argCount++] = &DM_GET_TOKEN_ARG_STR; + + //pArgs[argCount++] = &DM_RECIPIENT_ARG_STR; + + // Setup claims arg + pClaimsStr = malloc(claimStrLen + 10); + sscs_strcpy(pClaimsStr, &DM_REQUIRED_CLAIMS_ARG_STR); + sscs_strcat(pClaimsStr, "=\""); + + for (i = 0; i0) + { + sscs_strcat(pClaimsStr, " "); + } + sscs_strcat(pClaimsStr, pClaims[i]); + } + } + + sscs_strcat(pClaimsStr, "\""); + pArgs[argCount++] = pClaimsStr; + + // OPTIONAL Claims + //pArgs[argCount++] = &DM_OPTIONAL_CLAIMS_ARG_STR; + + // Token Type + pArgs[argCount++] = &DM_TOKEN_TYPE_ARG_STR; + pArgs[argCount++] = &DM_MAPTOSIMPLE_ARG_STR; + + + // Output file + pFileName = malloc(sscs_strlen(&DM_TOKEN_OUTPUT_FILE_ARG_STR) + sscs_strlen(filename) + 10); + + sscs_strcpy(pFileName, &DM_TOKEN_OUTPUT_FILE_ARG_STR); + sscs_strcat(pFileName, "=\""); + sscs_strcat(pFileName, filename); + sscs_strcat(pFileName, "\""); + pArgs[argCount++] = pFileName; + + // launch selector + printf("ARGS\r\n"); + for (i = 0; i 0) + { + sscanf(line, "%s %s", claimURI, claimvalue); + + // fill basic credential + if (!strcmp(claimURI, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname")) + { + strcpy(basicCred->username, claimvalue); + basicCred->unLen = strlen(claimvalue); + } + else if (!strcmp(claimURI, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname")) + { + strcpy(basicCred->password, claimvalue); + basicCred->pwordLen = strlen(claimvalue); + } + else + { + printf("Claim did not match anything\r\n"); + } + } + + // close the token file + fclose(tokenfile); + + // remove the file + remove(filename); + + return 0; + } + + + // Free resources +Exit: + printf("Free resources\r\n"); + if (pClaimsStr) + { + free(pClaimsStr); + } + + if (pFileName) + { + free(pFileName); + } + + for (i=0; i #include - #include "micasa_types.h" #include "micasa.h" #include "sscs_lldefs.h" @@ -31,6 +30,8 @@ #include "sscs_cache.h" #include "sscs_utf8.h" +#include "cardselector.h" + // delimited tags //static SS_UTF8_T SSCS_CRED_SET_DELIMITED[] = {'S','S','_','C','r','e','d','S','e','t',':',0}; static SS_UTF8_T SSCS_CRED_SET_DELIMITED[] = {"SS_CredSet:"}; @@ -48,6 +49,9 @@ static SS_UTF8_T SSCS_BINARY_SECRET_DELIMITED[] = {"SS_Binary:"}; static SS_UTF8_T SSCS_OBITUARY_DELIMITED[] = {"SS_Obituary:"}; #define SSCS_OBITUARY_CHARS_DELIMITED 13 +static SS_UTF8_T SSCS_DIGIME[] = {"DIGIME"}; +#define SSCS_DIGIME_LEN 7; + #define sscsshs_AddSHSBinaryEntry sscsshs_AddSHSEntry @@ -3194,6 +3198,49 @@ miCASAGetCredential return NSSCS_E_SYSTEM_FAILURE; } +#ifdef SSCS_LINUX_PLAT_F + //NOTE: this code calls the CardSelector if CASA is configured for this secret + //Any secret in this form: "DIGIMExxxxxx" + + if(appSecretID && (appSecretID->len > 1)) + { + // let's look for it. + secID.type = SSCS_CREDENTIAL_TYPE_F; + secID.len = (appSecretID->len + 6); + sscs_Utf8Strncpy(secID.name, SSCS_DIGIME, 7); + sscs_Utf8Strcat(secID.name, appSecretID->id); + + printf("Looking for mapping for card: %s {%d}\r\n", secID.name, secID.len); + + // get a new handle + if(secretHandle) + { + miCASA_DestroySHSHandle(secretHandle); + } + + secretHandle = miCASA_CreateSHSHandle(); + + rcode = miCASAReadSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, &readData, NULL); + if(rcode == NSSCS_SUCCESS) + { + printf("Found mapping, launch card selector\r\n"); + rcode = launchSelector(secretHandle, basicCred); + if (rcode == 0) + { + return rcode; + } + else + { + printf("selector returned error: %d\r\n", rcode); + } + } + else + { + printf("No mapping found\r\n"); + } + } +#endif + // 1&2. look up the SS_App for this secretID, if not found use the sharedSecretID secID.type = SSCS_APPLICATION_TYPE_F; secID.len = appSecretID->len; @@ -3476,6 +3523,33 @@ miCASASetCredential return NSSCS_E_SYSTEM_FAILURE; } + //NOTE: return success if the CASA is configured to map this secret. + if(appSecretID && (appSecretID->len > 1)) + { + // let's look for it. + secID.type = SSCS_CREDENTIAL_TYPE_F; + secID.len = (appSecretID->len + 6); + sscs_Utf8Strncpy(secID.name, SSCS_DIGIME, 7); + sscs_Utf8Strcat(secID.name, appSecretID->id); + + + // get a new handle + if(secretHandle) + { + miCASA_DestroySHSHandle(secretHandle); + } + + secretHandle = miCASA_CreateSHSHandle(); + + rcode = miCASAReadSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, &readData, NULL); + if(rcode == NSSCS_SUCCESS) + { + printf("Found mapping on SetCredential, return success\r\n"); + return rcode; + } + } + + // 1&2. Look up the SS_App for this secretID in case we should use an shared override, // if not found use the sharedSecretID passed in. secID.type = SSCS_APPLICATION_TYPE_F;