/***********************************************************************
 * 
 *  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.
 * 
 ***********************************************************************/


/* Sample code for C Language miCASA APIs */

#include <stdio.h>
#include <stdlib.h>

#ifdef WIN32
#include <conio.h>
#include <windows.h>
#else
#define getch(x) getchar(x);
#endif


#include <time.h>
#include <string.h>
#include <sscs_utf8.h>
#include <micasa.h>
#include <sscs_cache.h>


///////////////////////////////////////////////////////////////////////



void Pause()
{ 
	printf("\nPress a key ==>\n");
	getch();
} /* end of Pause */



void ReadKey()
{		
	int rcode = 0;
	char inputID[20];
	char inputKey[20];
	char inputValue[128] = {0};
	uint32_t valueLen = 128;
	uint32_t bytesRequired = 0;
	
	SSCS_SECRETSTORE_T 		store = {0};
	SSCS_SECRET_ID_T		appSecretId = {0};
	SSCS_SECRET_ID_T		sharedSecretId = {0};
	void					*context;
	SSCS_KEYCHAIN_ID_T 		kc = {0};
	
	SSCS_EXT_T ext = {0};
	
	printf("Enter secretID: ");		
	gets(inputID);

	printf("Enter Key: ");		
	gets(inputKey);		

	if ((sscs_Utf8Strlen(inputID) > 0) &&
		(sscs_Utf8Strlen(inputKey) > 0))
		
	{
		appSecretId.len = sscs_Utf8Strlen(inputID) + 1;
		sscs_Utf8Strcpy(appSecretId.id, inputID);

		printf("SAMPLE: Calling miCASAReadKey\r\n");

		// open secretStore
		sscs_Utf8Strcpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID);
		store.version = 1;
		context = miCASAOpenSecretStoreCache(&store, 0, NULL);

		if (context == NULL)
		{
			return; // NSSCS_E_SYSTEM_FAILURE;
		}

		sscs_Utf8Strcpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID);
		kc.len = SSCS_S_KC_ID_CHARS;

		rcode = miCASAReadKey(context, 
			0, 
			&kc, 
			&appSecretId, 
			inputKey, 
			strlen(inputKey)+1, 
			inputValue, 
			&valueLen, 
			NULL, 
			&bytesRequired,
			&ext);

		miCASACloseSecretStoreCache(context, 0, NULL);

		if (rcode)
		{
			printf("miCASAReadKey returned %d\r\n", rcode);
			Pause();
		}
		else
		{
			//set null			
			//memcpy(inputValue[valueLen + 1],
			printf("KeyValue is %s\r\n", inputValue);
		}
	}
}


void WriteKey()
{		
	int rcode = 0;
	char inputID[20];
	char inputKey[20];
	char inputValue[20];
	
	SSCS_SECRETSTORE_T 		store = {0};
	SSCS_SECRET_ID_T		appSecretId = {0};
	SSCS_SECRET_ID_T		sharedSecretId = {0};
	void					*context;
	SSCS_KEYCHAIN_ID_T 		kc = {0};
	
	SSCS_EXT_T ext = {0};
	
	printf("Enter secretID: ");		
	gets(inputID);

	printf("Enter Key: ");		
	gets(inputKey);
	
	printf("Enter Value: ");		
	gets(inputValue);	

	if ((sscs_Utf8Strlen(inputID) > 0) &&
		(sscs_Utf8Strlen(inputKey) > 0) &&
		(sscs_Utf8Strlen(inputValue) > 0))
	{
		appSecretId.len = sscs_Utf8Strlen(inputID) + 1;
		sscs_Utf8Strcpy(appSecretId.id, inputID);

		printf("SAMPLE: Calling miCASAWriteKey\r\n");

		// open secretStore
		sscs_Utf8Strcpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID);
		store.version = 1;
		context = miCASAOpenSecretStoreCache(&store, 0, NULL);

		if (context == NULL)
		{
			return; // NSSCS_E_SYSTEM_FAILURE;
		}

		sscs_Utf8Strcpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID);
		kc.len = SSCS_S_KC_ID_CHARS;

		rcode = miCASAWriteKey(context, 
			0, 
			&kc, 
			&appSecretId, 
			inputKey, 
			strlen(inputKey)+1, 
			inputValue, 
			strlen(inputValue)+1, 
			NULL, 
			&ext);

		miCASACloseSecretStoreCache(context, 0, NULL);

		if (rcode)
		{
			printf("miCASAWriteKey returned %d\r\n", rcode);
			Pause();
		}
	}
}

void AddSecret()
{		
	int rcode = 0;
	char inputID[20];
	char inputUsername[20];
	char inputPassword[20];

	SSCS_BASIC_CREDENTIAL	credential = {0};
	SSCS_SECRET_ID_T		appSecretId = {0};
	SSCS_SECRET_ID_T		sharedSecretId = {0};
	
	SSCS_EXT_T ext = {0};
	
	printf("Enter secretID: ");		
	gets(inputID);

	printf("Enter Username: ");		
	gets(inputUsername);
	
	printf("Enter Password: ");		
	gets(inputPassword);	

	if ((sscs_Utf8Strlen(inputID) > 0) &&
		(sscs_Utf8Strlen(inputUsername) > 0) &&
		(sscs_Utf8Strlen(inputPassword) > 0))
	{
		appSecretId.len = sscs_Utf8Strlen(inputID) + 1;
		sscs_Utf8Strcpy(appSecretId.id, inputID);

		credential.unFlags = USERNAME_TYPE_CN_F;
		sscs_Utf8Strcpy(credential.username, inputUsername);
		credential.unLen = sscs_Utf8Strlen(inputUsername) + 1;

		sscs_Utf8Strcpy(credential.password, inputPassword);
		credential.pwordLen = sscs_Utf8Strlen(inputPassword) + 1;

		printf("SAMPLE: Calling miCASASetCredential\r\n");
		// sets the credential for this app
		rcode = miCASASetCredential(            
			0,
			&appSecretId,				
			NULL,						
			SSCS_CRED_TYPE_BASIC_F,		
			&credential,				
			NULL						
		);

		if (rcode)
		{
			printf("Add Secret returned %d\r\n", rcode);
			Pause();
		}
	}
}

void DisplaySecret()
{

	int rcode = 0;
	char inputID[20];
	int32_t credtype = SSCS_CRED_TYPE_BASIC_F;

	SSCS_BASIC_CREDENTIAL	credential = {0};
	SSCS_SECRET_ID_T		appSecretId = {0};
	SSCS_SECRET_ID_T		sharedSecretId = {0};
	
	SSCS_EXT_T ext = {0};
	
	printf("Enter secretID to display: ");		
	gets(inputID);

	if (sscs_Utf8Strlen(inputID) > 0)
	{
		appSecretId.len = sscs_Utf8Strlen(inputID) + 1;
		sscs_Utf8Strcpy(appSecretId.id, inputID);

		// set name type we desire
		credential.unFlags = USERNAME_TYPE_CN_F;

		// gets the credential
		rcode = miCASAGetCredential(            
			0,
			&appSecretId,				
			NULL,			 			
			&credtype, //SSCS_CRED_TYPE_BASIC_F,		
			&credential,				
			NULL						
		);

		if (rcode == NSSCS_SUCCESS)
		{
			printf("Credential for: %s\r\n", appSecretId.id);
			printf("Username: %s\r\n", credential.username);
			printf("Password: %s\r\n", credential.password);
		}
		else
		{
			printf("Error: %d\r\n", rcode);
			Pause();
		}
	}
}

void RemoveSecret()
{
	int rcode = 0;
	char inputID[20];

	SSCS_BASIC_CREDENTIAL	credential = {0};
	SSCS_SECRET_ID_T		appSecretId = {0};
	SSCS_SECRET_ID_T		sharedSecretId = {0};
	
	SSCS_EXT_T ext = {0};
	
	printf("Enter secretID to remove: ");		
	gets(inputID);

	if (sscs_Utf8Strlen(inputID) > 0)
	{
		appSecretId.len = sscs_Utf8Strlen(inputID) + 1;
		sscs_Utf8Strcpy(appSecretId.id, inputID);

		// set name type we desire
		credential.unFlags = USERNAME_TYPE_CN_F;

		// gets the credential
		rcode = miCASARemoveCredential(            
			0,
			&appSecretId,		
			NULL, 				
			NULL
		);

		if (rcode == NSSCS_SUCCESS)
		{
			printf("Credential %s removed\r\n", inputID);						
		}
		else
		{
			printf("Error: %d\r\n", rcode);
			Pause();
		}
	}	
}

void RunTest()
{
	{
		SSCS_BASIC_CREDENTIAL	credential = {0};
		SSCS_SECRET_ID_T		appSecretId = {0};
		int32_t credtype =  SSCS_CRED_TYPE_BASIC_F;
		
		int rcode = 0;
		int iFlags = 0;

		sscs_Utf8Strcpy(appSecretId.id, "NativeC.AppSecretID");
		appSecretId.len = sscs_Utf8Strlen(appSecretId.id) + 1;
		
		credential.unFlags = USERNAME_TYPE_CN_F;
		sscs_Utf8Strcpy((char*)credential.username, "SampleUsername");
		credential.unLen = sscs_Utf8Strlen(credential.username) + 1;

		sscs_Utf8Strcpy((char*)credential.password, "SamplePassword");
		credential.pwordLen = sscs_Utf8Strlen(credential.password) + 1;

		printf("Setting %s\r\n", appSecretId.id);
		printf("   Username: %s\r\n", credential.username);
		printf("   Password: %s\r\n", credential.password);

		// sets the credential for this app
		rcode = miCASASetCredential(            
			iFlags,
			&appSecretId,				
			NULL,			 			
			SSCS_CRED_TYPE_BASIC_F,		
			&credential,				
			NULL						
		);

		credential.unFlags = USERNAME_TYPE_EMAIL_F;
		sscs_Utf8Strcpy((char*)credential.username, "Username@novell.com");
		credential.unLen = sscs_Utf8Strlen(credential.username) + 1;

		sscs_Utf8Strcpy((char*)credential.password, "SamplePassword");
		credential.pwordLen = sscs_Utf8Strlen(credential.password) + 1;

		// sets the credential for this app
		rcode = miCASASetCredential(            
			iFlags,
			&appSecretId,				
			NULL,			 			
			SSCS_CRED_TYPE_BASIC_F,		
			&credential,				
			NULL						
		);

		credential.unFlags = USERNAME_TYPE_LDAP_DN_F;
		sscs_Utf8Strcpy((char*)credential.username, "cn=user,o=novell");
		credential.unLen = sscs_Utf8Strlen(credential.username) + 1;

		sscs_Utf8Strcpy((char*)credential.password, "SamplePassword");
		credential.pwordLen = sscs_Utf8Strlen(credential.password) + 1;

		// sets the credential for this app
		rcode = miCASASetCredential(            
			iFlags,
			&appSecretId,				
			NULL,						
			SSCS_CRED_TYPE_BASIC_F,		
			&credential,				
			NULL						
		);

		credential.unFlags = USERNAME_TYPE_NDS_DN_F;
		sscs_Utf8Strcpy((char*)credential.username, "Username.novell");
		credential.unLen = sscs_Utf8Strlen(credential.username) + 1;

		sscs_Utf8Strcpy((char*)credential.password, "SamplePassword");
		credential.pwordLen = sscs_Utf8Strlen(credential.password) + 1;

		// sets the credential for this app
		rcode = miCASASetCredential(            
			iFlags,
			&appSecretId,				
			NULL,			 			
			SSCS_CRED_TYPE_BASIC_F,		
			&credential,				
			NULL						
		);

	
	
		// get the stuff back now
		memset(&credential, 0, sizeof(SSCS_BASIC_CREDENTIAL));
		
		credential.unLen = NSSCS_MAX_USERID_LEN;
		credential.pwordLen = NSSCS_MAX_PWORD_LEN;
		credential.unFlags = USERNAME_TYPE_CN_F;
				
		// gets the specific credential
		rcode = miCASAGetCredential(            
			iFlags,
			&appSecretId,				
			NULL,						
			&credtype, //SSCS_CRED_TYPE_BASIC_F,		
			&credential,				
			NULL						
		);


		if (rcode == NSSCS_SUCCESS)
		{
			printf("Getting Credential: %s\r\n", appSecretId.id);
			printf("   Username: %s\r\n", credential.username);
			printf("   Password: %s\r\n", credential.password);
		}
		else
		{					
			printf("ERROR getting Credential: %d\r\n", rcode);
			Pause();
		}

		printf("Removing Credential\r\n");
		rcode = miCASARemoveCredential(
			iFlags,
			&appSecretId,
			NULL,
			NULL
			);

		if (rcode != NSSCS_SUCCESS)
			printf("Error removing Credential: %d\r\n", rcode);


		// get the stuff back now
		memset(&credential, 0, sizeof(SSCS_BASIC_CREDENTIAL));
		
		credential.unLen = NSSCS_MAX_USERID_LEN;
		credential.pwordLen = NSSCS_MAX_PWORD_LEN;
		credential.unFlags = USERNAME_TYPE_CN_F;
				
		// gets the specific credential
		rcode = miCASAGetCredential(            
			iFlags,
			&appSecretId,				
			NULL,						
			&credtype, //SSCS_CRED_TYPE_BASIC_F,		
			&credential,				
			NULL						
		);


		if (rcode == NSSCS_E_INVALID_SECRET_ID)
			printf("Credential does not exist as expected -- SUCCESS\r\n");
		else
		{
			printf("Credential exists, when it should not -- FAILED\r\n");
			Pause();
		}



		printf("Test completed\r\n");

	}

}


void RunTests()
{

	char runtimes[6];
	int iCount = 1;
	int iTemp = 0;
	int i = 0;

	printf("Enter number interations to run (default 1): ");	
	gets(runtimes);

	iTemp = atoi(runtimes);
	if (iTemp > 1)
		iCount=iTemp;

	for (i=0; i<iCount; i++)
	{
		RunTest();
		printf("\r\n");
	}
}



void displayMenu()
{
	
	int c;

	while (1)
	{
		printf("\r\n");
		printf("********** Menu **********\r\n");
		printf("*  1. Add secret         *\r\n");
		printf("*  2. Display secret     *\r\n");
		printf("*  3. Remove secret      *\r\n");				
		printf("*  4. Run automated test *\r\n");		
		printf("*  5. WriteKey           *\r\n");
		printf("*  6. ReadKey            *\r\n");
		printf("*  7. Quit               *\r\n");
		printf("**************************\r\n");


		printf("Select option and press Enter\r\n");			
		c = getchar();
		
		// get return
		getchar();

		if (c == '7')
			return;
		else if (c == '1')
			AddSecret();			
		else if (c == '2')
			DisplaySecret();
		else if (c == '3')
			RemoveSecret();
		else if (c == '4')
			RunTests();
		else if (c == '5')
			WriteKey();
		else if (c == '6')
			ReadKey();


	}
	
}



/*
 * NAME - main
 *
 * DESCRIPTION
 *	miCASA test program.		   
 *		   
 */
int	main
(
	int 		argc, 
	char 		**argv
)
{ /* beginning of the call */
/* ########################## DECLARATIONS START HERE ######################### */
	

/* ############################## CODE STARTS HERE ############################ */

	printf("***************************************************************\r\n");
	printf("**************   miCASA Sample program in C      **************\r\n");
	printf("***************************************************************\r\n");
	displayMenu();
	exit(0);


/* ########################## CODE ENDS HERE ##################### */
}