#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <windows.h>
#include <lm.h>
#include <cmqc.h>
#include <cmqxc.h>
#include <time.h>



void MQStart() {;}
char logStr[80], tmpStr[MQ_EXIT_DATA_LENGTH + 1];
char *chlTypes[8] = {"Unknown", "Sender", "Server", "Receiver", "Requester", "All", "ClientConn", "ServerConn"};
FILE*      hTestLog;


void MQENTRY CHANNELEXIT (  PMQCXP  pChannelExitParms,  PMQCD   pChannelDefinition, PMQLONG pDataLength, PMQLONG pAgentBufferLength, PMQVOID pAgentBuffer,  PMQLONG pExitBufferLength, PMQPTR  pExitBufferAddr)
{
	struct tm *newtime;
	time_t aclock;
	char *pTimeStr;

	PMQCXP  pParms = pChannelExitParms;
	PMQCD   pChDef = pChannelDefinition;

	#ifdef _TRACE
		hTestLog = fopen("\\sec_trace.log", "a+");
		printf("TRACE defined!\n");
    	fprintf(hTestLog, "Entering security exit routine.\n");
	#else
		printf("TRACE NOT defined!\n");
	#endif

    	time( &aclock );
    	newtime = localtime( &aclock );
		pTimeStr = asctime(newtime);
		pTimeStr[strlen(pTimeStr) - 1] = '\0';

	#ifdef _TRACE
		sprintf(logStr, "%s: %s channel %s\n", pTimeStr, chlTypes[pChannelDefinition->ChannelType],
	    		strncpy(tmpStr, pChannelDefinition->ChannelName, MQ_CHANNEL_NAME_LENGTH));
	    fprintf(hTestLog, logStr);
	#endif

  	if (pParms->ExitId==MQXT_CHANNEL_SEC_EXIT)
  	{
   		switch (pParms->ExitReason)
   		{
     			case MQXR_INIT: pParms->ExitResponse = InitSExit(pChannelExitParms, pChannelDefinition,pDataLength,pAgentBufferLength, pAgentBuffer);
								#ifdef _TRACE
     								fprintf(hTestLog,"ExitReason = Channel Initialization\n");
								#endif
                     			break;
     			case MQXR_INIT_SEC:	pParms->ExitResponse = MQXCC_SUPPRESS_FUNCTION;
								#ifdef _TRACE
						     		fprintf(hTestLog,"ERROR!! - Unexpectedly invoked with MQXR_INIT_SEC - closing channel\n");
								#endif
                     			break;
     			case MQXR_SEC_MSG:	pParms->ExitResponse = receiveSecMsg(pChannelExitParms,pChannelDefinition,pDataLength,*pAgentBufferLength,pAgentBuffer);
								#ifdef _TRACE
	     							fprintf(hTestLog,"ExitReason = Security Message Received\n");
								#endif
                     			break;
     			case MQXR_TERM:	memset(pParms->ExitUserArea,0,sizeof(pParms->ExitUserArea));
                     			pParms->ExitResponse = MQXCC_OK;
								#ifdef _TRACE
	     							fprintf(hTestLog,"ExitReason = Terminate the Channel\n");
								#endif
                     			break;
     			default:		pParms->ExitResponse = MQXCC_SUPPRESS_FUNCTION;
								#ifdef _TRACE
						     		fprintf(hTestLog,"ERROR!! Invoked with unexpected exitreason\n");
								#endif
                     			break;
    		}
   	}
   	else
   	{
     	pParms->ExitResponse = MQXCC_SUPPRESS_FUNCTION;
		#ifdef _TRACE
	    	fprintf(hTestLog, "ERROR!! - Unexpected invocation");
		#endif
     	return;
   	}
	#ifdef _TRACE
		fprintf(hTestLog, "Leaving security exit routine.\n");
		fprintf(hTestLog, "\n\n");
		fclose(hTestLog);
	#endif
	return;
}
MQLONG InitSExit(PMQCXP     I_pCEParms, PMQCD      I_pCDefinition,PMQLONG    I_pDLength,PMQLONG    I_pABufferLength,PMQVOID    I_pABuffer )
{
	memset(I_pCEParms->ExitUserArea,0,sizeof(I_pCEParms->ExitUserArea));
 	return MQXCC_OK;
}
MQLONG receiveSecMsg(PMQCXP     pCEParms, PMQCD      pCDefinition,PMQLONG    pDLength,MQLONG     ABufferLength,PMQVOID    pABuffer)
{

	MQBYTE ExitData[] = "WMQTool";
	char validID[50];
 	char validSV[50] = "localhost";
	char validPW[50];

	char *vvalidID;
	char *vvalidSV;
	char *vvalidPW;

	char pswdpref[] = "wpwd";
	char usidpref[] = "wuid";
	const int prefixLength = 4;

	DWORD nStatus;
	DWORD Err;
	HANDLE	phToken = NULL;

	int length;
	int rcode = 1;

	length = *pDLength;

	vvalidID = validID;
	vvalidPW = validPW;
	vvalidSV = validSV;

	memset(validID,0,sizeof(validID));
	memset(validPW,0,sizeof(validPW));

	if (*pDLength == 0 )
	{
		#ifdef _TRACE
			fprintf (hTestLog, "ERROR!! - No security message received in Agent Buffer - closing channel \n");
		#endif
		return MQXCC_SUPPRESS_FUNCTION;
	}
	else
	{
		rcode = strncmp(pABuffer,usidpref,prefixLength);
		if ( rcode == 0 )
		{
			strncpy(pCEParms->ExitUserArea,pABuffer,length);

			memset(pABuffer,0,length);
			if ( sizeof(ExitData) <= ABufferLength)
			{
				memcpy(pABuffer,ExitData,sizeof(ExitData));
				*pDLength = sizeof(ExitData);
				pCEParms->ExitResponse2 = MQXR2_USE_AGENT_BUFFER;
			}
			return MQXCC_SEND_AND_REQUEST_SEC_MSG;
		}
		else
		{
			rcode = strncmp(pABuffer,pswdpref,prefixLength);
			if (rcode == 0)
			{
				strncpy(vvalidID,pCEParms->ExitUserArea,sizeof(pCEParms->ExitUserArea));
				strncpy(vvalidPW,pABuffer,length);
//				nStatus = LogonUser(vvalidID+prefixLength,vvalidSV,vvalidPW+prefixLength, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT,&phToken);
				nStatus = LogonUser(vvalidID+prefixLength,NULL,vvalidPW+prefixLength, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,&phToken);
				if (nStatus == 0)
				{
					Err = GetLastError();
					#ifdef _TRACE
						fprintf(hTestLog,"ERROR!! - Logon error Err = %d \n", Err);
						fprintf (hTestLog,"ERROR!! - Userid not verified - closing channel\n");
					#endif
					return MQXCC_SUPPRESS_FUNCTION;
				}
				else
				{
					#ifdef _TRACE
						fprintf(hTestLog,"System logon successful by userid %s\n",vvalidID+prefixLength);
					#endif

					memset(pCDefinition->MCAUserIdentifier,0,sizeof(pCDefinition->MCAUserIdentifier));
					strncpy(pCDefinition->MCAUserIdentifier,validID+prefixLength,(sizeof(validID)-prefixLength));

					memset(pABuffer,0,length);
					return MQXCC_OK;
				}
			}
			else
			{
				#ifdef _TRACE
					fprintf(hTestLog,"ERROR!invalid request - closing channel\n");
				#endif
				memset(pABuffer,0,length);
				return MQXCC_SUPPRESS_FUNCTION;
			}
		}
	}
}

