Added code to call card selector for mapped secrets (WIP)

This commit is contained in:
Jim Norman 2008-02-28 18:34:43 +00:00
parent bdf7cdcf8d
commit 32a045af7c
5 changed files with 586 additions and 1 deletions

View File

@ -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);

View File

@ -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 <stdlib.h>
#include <memory.h>
#include <stdio.h>
#include <unistd.h>
#include <wait.h>
#include <asm/ioctls.h>
#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; i<MAXARGS; i++)
{
if (pClaims[i] != NULL)
{
// add a space
if (i>0)
{
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<MAXARGS; i++)
{
if (pArgs[i] != NULL)
{
printf("%s\r\n", pArgs[i]);
}
}
f_exec(dmPaths[indexToDigitalMeApp], pArgs, NULL, NULL);
// read the file
tokenfile = fopen(filename, "r");
if (tokenfile != NULL)
{
while (getLine(line, 256, tokenfile) > 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<MAXCLAIMS; i++)
{
if (pClaims[i] != 0)
{
printf("freeing claim: %d\r\n", i);
free(pClaims[i]);
}
}
return -1;
}
}

View File

@ -48,6 +48,7 @@ MODULE_NAME =libmicasa
MODULE_EXT =so
CFILES = ../sscs_ll.c \
../cardselector.c \
../sscs_ndk.c
CSFILES_CSC :=

View File

@ -1,3 +1,4 @@
OBJS=\
sscs_ll.$(O)\
cardselector.$(0)\
sscs_ndk.$(O)

View File

@ -23,7 +23,6 @@
#include <stdlib.h>
#include <memory.h>
#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;