⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccontrolthread.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:

void
CControlThread::ConfigComplete()
{
	uchar *p, *e;
	short sl, inx;
	char s[128];
	long codec;

	// Configuration complete, start call
	mStatusPane->AddStatus(0, "Configuration complete.");
	mControlState = _con_Phone;
	mSoundInput->Record(FALSE);
	mPFWindow->SetDecoderList((uchar *)mVoiceDecoders,
								mNumDecoders);
	mPFWindow->SetEncoderList((uchar *)mVoiceEncoders,
								mNumEncoders);
	BUFFER_TO_LONG(mEncryptor, codec);
	mPFWindow->SetEncryption(codec, 0);
	mPFWindow->ShowStatus();
	mTransport->BindMediaStreams();
	SetSpeaker(mOriginator || mFullDuplex);
	BUFFER_TO_LONG(mVoiceEncoders, codec);
	mPFWindow->SetEncoder(codec);
	mSoundInput->SetCodec(codec);
	mSoundInput->SetOutput(mOutHPP, mSoundOutQ);
	mSoundInput->Pause(TRUE);
	if(mHaveChannel)
		mSoundInput->Record(TRUE);
	mChangingEnc = TRUE;
	if(gPacketWatch)
		gPacketWatch->SetHPPQueue(mSoundOutQ);
	p = e = (uchar *)pgp_malloc(5);
	*e++ = _ctp_OpenVoice;
	LONG_TO_BUFFER(codec, e);	e+=4;
	mControlOutQ->Send(_mt_controlPacket, p, e-p);
	if(mUseWordList)
	{
		for(sl=0,inx=0;inx<mAuthBytes;inx++)
		{
			sprintf(&s[sl], "%s\r", (inx==1 || inx==3) ?
						hashWordListOdd[mAuthInfo[inx]] :
						hashWordListEven[mAuthInfo[inx]]);
			sl = strlen(s);
		}
	}
	else
	{
		for(sl=0,inx=0;inx<mAuthBytes;inx++)
		{
			sprintf(&s[sl], "%02x\r", mAuthInfo[inx]);
			sl = strlen(s);
		}
	}
	if(mPrime)
		mPFWindow->ShowAuthParams(s);
#ifdef	PGPXFER
	if(mSupportsFileXfer)
	{
		mXferResult = 0;
		mXferQueue = new CMessageQueue(16);
		(mXfer = new CXferThread(mPFWindow, mXferWindow, mOutHPP, mXferQueue,
			mControlOutQ, (void **)&mXferResult))->Resume();
		mPFWindow->AllowXfers(TRUE);
		mInHPP->SetXferQueue(mXferQueue);
		mOutHPP->SetXferThread(mXfer);
		mXferWindow->SetXferThread(mXfer);
	}
#endif
}

void
CControlThread::SetupTransport(enum ContactMethods method)
{
	short result=0;
	 
	if(!mTransport)
	{
		switch(method)
		{
			case _cme_Serial:
				mTransport = new CPFTSerial(&gPGFOpts.sopt, mPFWindow, &result);
				break;
			case _cme_Internet:
				mTransport = new CPFTInternet(mPFWindow, this, &result);
				break;
			case _cme_AppleTalk:
#ifndef PGP_WIN32
				mTransport = new CPFTAppleTalk(mPFWindow, this, &result);
#endif
				break;
		}
		if(result)
		{
			delete mTransport;
			mTransport = NULL;
		}
	}
}

void
CControlThread::StartPhone()
{
	mControlState = _con_Configuring;
	mConfigState = _cts_Hello;
	mRemotePublicName[0]=0;
	mRemoteSystemType = _pst_Generic;
	pgp_memcpy(mEncryptor, sCryptorHash[_enc_none], 4);
	mNumPrimes = 0;
	mPrime = NIL;
	if(mDHPublic)
		pgp_free(mDHPublic);
	if(mDHPrivate)
		pgp_free(mDHPrivate);
	mDHPublic = mDHPrivate = NIL;
	mAuthenticated = mUseWordList = mFullDuplex = mAllowNone =
		mFlipInProgress = mChangingEnc = mChangingDec =
		mSupportsFileXfer = FALSE;
	mRemoteWindow = 1;
	mAuthBytes = 4;
	bnInit();
	byteFifoInit(&mSharedSecret);
	byteFifoInit(&mOAuthentication);
	byteFifoInit(&mAAuthentication);
	gPacketWatch->InitCall();	// reset packet watch
	mControlOutQ = new CMessageQueue(4);
	mSoundOutQ = new CMessageQueue(10);
	mInHPPResult = mOutHPPResult = 0;
	(mInHPP = new CPFPacketsIn(gPGFOpts.popt.connection != _cme_Serial,
		mPFWindow, mSoundOutput, mTransport, mMsgQueue,
		mControlOutQ, mSoundOutput->GetPlayQueue(),
		(void **)&mInHPPResult))->Resume();
	(mOutHPP = new CPFPacketsOut(gPGFOpts.popt.connection != _cme_Serial,
		mPFWindow, mTransport, mSoundInput, mControlOutQ, mSoundOutQ,
		(void **)&mOutHPPResult))->Resume();
	mSoundInput->SetPacketThread(mOutHPP);
#ifdef CONFIGCALL
	// record sound until the call is configured
	mSoundInput->SetCodec('rand');
	mSoundInput->SetOutput(NIL, NIL);
	mSoundInput->Record(TRUE);
	SendHello();	//begin configuration
#else
	// this code exists to test calls without configuration packets
	// and without encryption
	mControlState = _con_Phone;
	mFullDuplex = TRUE;
	mPFWindow->ShowStatus();
	mSoundInput->SetCodec('GS5L');	// hardcoded default configuration
	mSoundInput->SetOutput(mOutHPP, mControlOutQ);
	mSoundInput->Record(TRUE);
	mSoundOutput->SetCodec('GS5L');
	mSoundOutput->Play(TRUE);
#endif
}

// CSoundOutput calls DropCoder when its underflow algorithm
// has determined that the coder currently in use is not
// adequately low CPU or low bandwidth for the connection.
// This tries not to but does partially assume the list of
// coders we got back intersected is listed in an estimate of
// decreasing order of coder complexity

void
CControlThread::DropCoder(ulong curCoder)
{
	short i;
	ulong curTime, codTime;
	long curcps, codcps;
	
	return;
	//This feature has been temporarily disabled.
	
	GetCoderReqs(curCoder, &curTime, &curcps);
	for(i=0;i<mNumDecoders;i++)
	{
		if(curCoder != mVoiceDecoders[i])
		{
			GetCoderReqs(mVoiceDecoders[i], &codTime, &codcps);
			if(codcps < curcps)
			{
				mMsgQueue->SendUnique(_mt_changeDecoder,
										(void *)mVoiceDecoders[i]);
				return;
			}
		}
	}
	mStatusPane->AddStatus(0,"Alternate coders exhausted, "
								"connection is hopeless.");
}

//	This function sets the "speaker" or the talking party in a half duplex
//	conversation.  It also passes the current information up to the window
//	so that the appropriate information can be displayed to the user

void
CControlThread::SetSpeaker(Boolean speaker)
{
	mHaveChannel = speaker;
	mSoundOutput->Play(!speaker || mFullDuplex);
	mPFWindow->SetSpeaker(speaker, mFullDuplex);
}

//	Other threads can call this function to abort a call
//	or cause the thread to exit

void
CControlThread::AbortSync(Boolean exit, Boolean remote)
{
	mControlState = _con_Disconnecting;
	if(mTransport)
		mTransport->AbortSync();
	if(exit)
	{
		mDone = TRUE;
		mMsgQueue->SendUnique(_mt_quit);
	}
	else if(remote)
		mMsgQueue->SendUnique(_mt_remoteAbort);
	else
		mMsgQueue->SendUnique(_mt_abort);
}

//	The following function is called when the user switches port information
//	or switches from Modem <-> Internet while the program is running.

void
CControlThread::ResetTransport()
{
	if(mTransport)
		mTransport->AbortSync();
	mMsgQueue->SendUnique(_mt_resetTransport);
}

#define GSM7INDEX	7
#define GSM7LINDEX	2

void
CControlThread::SetCoderList(CoderEntry *coders, short numCoders)
{
	mCoders = coders;
	mNumCoders = numCoders;
	if(gPacketWatch)
		gPacketWatch->SetGSMTimes(
			coders[GSM7INDEX].encTime, coders[GSM7LINDEX].encTime,
			coders[GSM7INDEX].decTime, coders[GSM7LINDEX].decTime);	//##### hardcoded GSM 7350/Lite
	if(coders[GSM7INDEX].encTime > 750)	// 1 second GSM encode took >70% of processor!
		PGFAlert("PGPfone has determined that this computer is probably too slow.", 0);
}

char *
CControlThread::GetCoderName(ulong coder)
{
	if(mCoders)
	{
		for(short inx = 0;inx<mNumCoders;inx++)
			if(coder == (ulong)mCoders[inx].code)
				return mCoders[inx].name;
	}
	return NIL;
}

void
CControlThread::GetCoderReqs(ulong coder, ulong *reqTime, long *reqcps)
{
	if(mCoders)
	{
		for(short inx = 0;inx<mNumCoders;inx++)
			if(coder == (ulong)mCoders[inx].code)
			{
				*reqTime = mCoders[inx].encTime;
				*reqcps = mCoders[inx].reqcps;
				return;
			}
	}
}

void
CControlThread::SendInfo()
{
	uchar *p, *e;
	short dInx, eInx, inx;
	
#ifdef DEBUGCONFIG
	mStatusPane->AddStatus(0,"SendInfo");
#endif
	// the following block of code sends the _ctp_Info packet
	// which is the first packet sent under cloak.  It
	// negotiates various parameters such as voice encoders,
	// duplex, sync, wordlist/hex, and # of authentication bytes
	p = e = (uchar *)pgp_malloc(512);
	pgpAssert(p);
	*e++ = _ctp_Info;
	if(!gPGFOpts.popt.idUnencrypted &&
		((mOriginator && gPGFOpts.popt.idOutgoing) ||
		(!mOriginator && gPGFOpts.popt.idIncoming)) &&
		gPGFOpts.popt.identity[0])
	{
		*e++ = _cti_PublicName;
		*e++ = strlen(gPGFOpts.popt.identity);
		strcpy((char *)e, gPGFOpts.popt.identity);
		e+= strlen((char *)e);
	}
	*e++ = _cti_SystemType;
	*e++ = 1;
#ifdef PGP_MACINTOSH
	*e++ = _pst_Macintosh;
#else
	*e++ = _pst_Generic;
#endif
	*e++ = _cti_Duplex;
	*e++ = 1;
	*e++ = (gPGFOpts.popt.fullDuplex);
	*e++ = _cti_WordList;	// We want the word list by default
	*e++ = 1;
	*e++ = 1;
	*e++ = _cti_AuthenticationBytes;// Number of Authentication Bytes
	*e++ = 1;
	*e++ = mAuthBytes;
	// Setup list of voice encoders and decoders
	LONG_TO_BUFFER(gPGFOpts.popt.prefCoder, mVoiceDecoders);
	dInx = 4;
	mNumDecoders = 1;
	if(gPGFOpts.popt.prefCoder != gPGFOpts.popt.altCoder)
	{
		LONG_TO_BUFFER(gPGFOpts.popt.altCoder, mVoiceDecoders+dInx);
		dInx+=4;
		mNumDecoders++;
	}
	mNumEncoders = 0;
	eInx = 0;
	pgpAssert(mCoders);
	for(inx = mNumCoders-1;inx>=0;inx--)
	{
		if((mCoders[inx].code != gPGFOpts.popt.prefCoder) &&
			(mCoders[inx].code != gPGFOpts.popt.altCoder) &&
			((mCoders[inx].reqSpeed <= gPGFOpts.sopt.maxBaud) ||
			(gPGFOpts.popt.connection != _cme_Serial)))
		{
			LONG_TO_BUFFER(mCoders[inx].code, mVoiceDecoders+dInx);
			dInx+=4;
			mNumDecoders++;
		}
		if((mCoders[inx].encTime < MAXCODERTIMETHRESHOLD) &&
			((mCoders[inx].reqSpeed <= gPGFOpts.sopt.maxBaud) ||
			(gPGFOpts.popt.connection != _cme_Serial)))
		{
			LONG_TO_BUFFER(mCoders[inx].code, mVoiceEncoders+eInx);
			eInx+=4;
			mNumEncoders++;
		}
	}
	*e++ = _cti_VoiceEncoders;	// Send our list of encoders
	*e++ = eInx;
	pgp_memcpy(e, mVoiceEncoders, eInx);
	e+=eInx;
	*e++ = _cti_VoiceDecoders;	// Send our list of decoders
	*e++ = dInx;
	pgp_memcpy(e, mVoiceDecoders, dInx);
	e+=dInx;
#ifdef PGPXFER
	*e++ = _cti_FileTransfer;
	*e++ = 2;
	SHORT_TO_BUFFER((short)MAXSAVEDOOPACKETS, e);	e+=2;
#endif
	mControlOutQ->Send(_mt_controlPacket, p, e-p);
}

Boolean
CControlThread::ReceiveInfo(uchar *data, short length)
{
	uchar *p, *e;
	ulong *cd;
	short len, num, inx, inx2, nd;
	Boolean good = TRUE;
	
#ifdef DEBUGCONFIG
	mStatusPane->AddStatus(0,"ReceiveInfo");
#endif
	len = 0;
	for(p=data,e=data+length;p<e;p+=len)
	{
		num = *p++;
		if(p == e)
		{
			good = FALSE;
			break;
		}
		len = *p++;
		if(e-p < len)
		{
			good = FALSE;
			break;
		}
		switch(num)
		{
			case _cti_PublicName:
				if(len>0)
				{
					if(len>63)
						len=63;
					pgp_memcpy(mRemotePublicName,p,len);
					mRemotePublicName[len]=0;
				}
				break;
			case _cti_SystemType:
				mRemoteSystemType = (enum SystType)*p;
				break;
			case _cti_Duplex:
				if(gPGFOpts.popt.fullDuplex && *p)
					mFullDuplex = TRUE;
				break;
			case _cti_Sync:
				//we dont support it, so it wont be negotiated
				break;
			case _cti_VoiceEncoders:
				num = len / 4;
				cd = (ulong *)p;
				for(inx=0;inx<mNumDecoders;inx++)
				{
					for(inx2=0;inx2<num;inx2++)
					{
						if(!memcmp(&mVoiceDecoders[inx*4],&cd[inx2],4))
							break;
					}
					if(inx2>=num)
					{
						if(inx<mNumDecoders-1)
							pgp_memcpy(&mVoiceDecoders[inx*4],
										&mVoiceDecoders[(inx+1)*4],
										(mNumDecoders-1-inx) * 4);
						mNumDecoders--;
						inx--;
					}
				}
				if(!mNumDecoders)
				{
					mStatusPane->AddStatus(0,
						"Could not negotiate a voice decoder.");
					good = FALSE;
				}
				break;
			case _cti_VoiceDecoders:
				nd = num = len / 4;
				cd = (ulong *)p;
				for(inx=0;inx<nd;inx++)
				{
					for(inx2=0;inx2<mNumEncoders;inx2++)
					{
						if(!memcmp(&mVoiceEncoders[inx2*4],&cd[inx],4))
							break;
					}
					if(inx2>=mNumEncoders)
					{
						if(inx<nd-1)
							pgp_memcpy(&cd[inx], &cd[inx+1], (nd-1-inx) * 4);
						num--;
					}
				}
				if(num > 32)
					num = 32;
				mNumEncoders = num;
				pgp_memcpy(mVoiceEncoders, p, num * 4);
				if(!mNumEncoders)
				{
					mStatusPane->AddStatus(0,
						"Could not negotiate a voice encoder.");
					good = FALSE;
				}
				break;
			case _cti_AuthenticationBytes:
				if(*p < mAuthBytes && *p >= 2)
					mAuthBytes = *p;
				break;
			case _cti_WordList:
				if(*p)
					mUseWordList = TRUE;
				break;
			case _cti_FileTransfer:
				mSupportsFileXfer = TRUE;
				BUFFER_TO_SHORT(p, mRemoteWindow);
				break;
			default:
				// unknown data, so ignore it
				break;
		}
	}	
	return good;
}

Boolean
CControlThread::ReceiveDHHash(uchar *data, short length)
{
	Boolean good = TRUE;
	
#ifdef DEBUGCONFIG
	mStatusPane->AddStatus(0,"ReceiveDHHash");
#endif
	if(length >= SHS_DIGESTSIZE)
		pgp_memcpy(mDHHash, data, SHS_DIGESTSIZE);
	else
		good = FALSE;
	return good;
}

void
CControlThread::SendDHHash()
{
	uchar *p, *e, alen[4];
	long authwrit;
	SHA hash;
	
#ifdef DEBUGCONFIG
	mStatusPane->AddStatus(0,"SendDHHash");
#endif
	// The following block of code sends the _ctp_DHHash packet
	// which sends a hash of the public Diffie-Hellman calculation
	// This is integral to the security by making sure that both
	// parties commit to a value before revealing the public
	// calculation
	p = e = (uchar *)pgp_malloc(512);
	pgpAssert(p);
	*e++ = _ctp_DHHash;
	// Calculate first half of the Diffie-Hellman
	mDHPublic = (uchar *)pgp_malloc(mPrime->length);
	mDHPrivate = (uchar *)pgp_malloc(mPrime->length);
	if(dhFirstHalf(mPrime->prime, mPrime->length, mPrime->expSize,
		dhGenerator, sizeof(dhGenerator),
		mDHPrivate, mPrime->length,
		mDHPublic) < 0)
		pgp_errstring("Diffie-Hellman error.");
	// Hash the Public field and commit to it by sending it to
	// the other side
	hash.Init();
	hash.Update(mDHPublic, mPrime->length);
	hash.Final(e);
	e+=SHS_DIGESTSIZE;
	SHORT_TO_BUFFER((short)(e-p), alen);
	authwrit = byteFifoWrite(mOriginator? &mOAuthentication : &mAAuthentication, alen, 2);
	pgpAssert(authwrit == 2);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -