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

📄 pgplicensenumbernet.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 3 页
字号:
typedef struct formUrlEncodedParam {
	const PGPByte *tok;
	PGPByte *value;
} formUrlEncodedParam;
static PGPError parseParams( const PGPByte *in, 
	PGPByte *ticket, PGPByte *scookie, PGPByte *ln, PGPByte *companyName, PGPByte *customerName, 
	PGPByte *la, PGPByte *groupid )
{
	PGPByte buf[kPGPLANet_ReceiveSize];
	PGPByte *p;
	const PGPByte *s;
	PGPUInt32 i;
	PGPUInt32 j;
	PGPSize len;
	PGPBoolean more;
	
	formUrlEncodedParam params[] = {
		{ tok_ticket, ticket },
		{ tok_scookie, scookie }, 
		{ tok_ln, ln }, 
		{ tok_companyName, companyName }, 
		{ tok_customerName, customerName },
		{ "la", la },
		{ "group_id", groupid }
	};

	for( i=0; i<sizeof(params)/sizeof(params[0]); i++ )  {
		if( params[i].value )
			params[i].value[0] = '\0';
	}

	/* process parameters */
	s = in;
	more = TRUE;
	while( more )  {
		PGPInt32 k;
		p = strchr( s, '&' );
		if( p != NULL )  {
			more = TRUE;
			*p = '\0';
		}
		else 
			more = FALSE;

		/* s points to the pair, decode it into buf */
		{
			/* remove line breaks and remove encoding */
			i=j=0;
			while( s[i]=='\r' )
				i++;
			len = strlen(s);
			if( len > sizeof(buf) )
				len = sizeof(buf);
			for( ; i<len; i++ )  {
				if( s[i]=='\r' || s[i]=='\n' || s[i]==' ')  
					continue;
				if( s[i]=='%' )  {
					if( len-i >= 3 )  {
						PGPUInt32 bv;
						PGPByte b[] = { s[i+1], s[i+2], '\0' };
						if( sscanf( b, "%02X", &bv ) )
							buf[j++] = (PGPByte)bv;
						i += 2;	/* two extra */
						continue;	/* one more i */
					}
					else	/* remove it */
						break;
				}
				if( s[i]=='+' )  {
					buf[j++] = ' ';
					continue;
				}
				buf[j++] = s[i];
			}
			buf[j] = '\0';
		}

		for( k=0; k<sizeof(params)/sizeof(params[0]); k++ )  {
			if( params[k].value!=NULL && strncmp( buf, params[k].tok, strlen(params[k].tok))==0 &&
				buf[strlen(params[k].tok)]=='=' )  
			{
				strcpy( params[k].value, buf+strlen(params[k].tok)+1 );
			}
		}

		if( more )
			s += strlen(s)+1;
	}

	return kPGPError_NoErr;
}

/* make authorization request, that will be sent to the website as 
   the main payload */
static PGPError makeAuthReq( PGPContextRef context, const PGPLicenseNumberRef ln,
	const PGPByte *customerName,
	const PGPByte *companyName,
	PGPByte buf[kPGPLANet_ReceiveSize] )  
{
	PGPError err = kPGPError_NoErr;
	PGPByte ln_b32[kPGPLicenseNumberMaxSize] = {'\0'};
	PGPLNExportBase32( context, ln, NULL, ln_b32 );

	buf[0] = '\0';
	if( ln_b32[0] != '\0' )  {
		PGPByte *hash_b64 = NULL;
		addFormUrlEncodedParam( tok_ln, ln_b32, buf );
		addFormUrlEncodedParam( tok_customerName, customerName, buf );
		addFormUrlEncodedParam( tok_companyName, companyName, buf );

		err = PGPLAGetNameHash( context, customerName, companyName, &hash_b64 );
		if( IsntPGPError( err ) )
			addFormUrlEncodedParam( tok_nameHash, hash_b64, buf );
			
		if( hash_b64 != NULL )
			PGPFreeData( hash_b64 );
	}
	else  {
		return kPGPError_CorruptData;
	}

	return err;
}

/* creates objects from authorization request */
PGPError pgpLAParseAuthenticationRequest(PGPContextRef context,
	const PGPByte *authReq, PGPLicenseNumberRef *ln, 
	PGPByte *custName, PGPByte *compName )
{
	PGPError err;
	PGPByte ln_b32[kPGPLANet_ReceiveSize];

	err = parseParams( authReq, 
		NULL, NULL, ln_b32, compName, custName, NULL, NULL );
	if( IsntPGPError(err) )  {
		err = PGPLNImportBase32( context, ln_b32, ln );
	}

	return err;
}

/* sends request for license authorization */
PGPError pgpLACreateNet(PGPContextRef context,
	const PGPByte *url, 
	const PGPLicenseNumberRef licenseNumber,
	const PGPByte *customerName,
	const PGPByte *companyName,
	PGPLicenseAuthorizationRef *buffer )
{
	PGPError err;
	PGPInternetAddress addr;
	PGPUInt16 port;
	PGPByte host_port[kPGPLANet_UrlMax];
	PGPByte resource[kPGPLANet_UrlMax];
	PGPByte out[kPGPLANet_ReceiveSize];
	PGPUInt32 httpError=0;
	PGPError remotePgpError=kPGPError_NoErr;
	PGPSocketRef socket = kInvalidPGPSocketRef;
	PGPByte ln_cust_comp_b64[kPGPLANet_SendSize];

	PGPByte ticket_b64[kPGPLANet_ReceiveSize];
	PGPByte scookie_b64[kPGPLANet_ReceiveSize];
	PGPByte IV[32];		/* for CBC IV */

	PGPByte *ticket_stub_b64 = NULL;
	PGPByte *ln_cust_comp_b64_encr_b64 = NULL;

	PGPByte postParams[kPGPLANet_ReceiveSize];

	pgpDHExchangeRef dhExchange = NULL;
	PGPSize tsize;

	PGPSize cipherBlockSize=0;
	PGPSymmetricCipherContextRef symmRef = kInvalidPGPSymmetricCipherContextRef;
	PGPCBCContextRef cbcContext = NULL;

	err = dhInitDL( context, 0 /*group*/, &dhExchange );
	if( IsPGPError(err) )
		return err;

	err = dhGenerate1( dhExchange );
	if( IsPGPError(err) )  {
		dhFree(dhExchange);
		return err;
	}

#if PGP_DEBUG_PRINT
	fprintf(stderr,"DH=");
	dhPrintBuffer( dhExchange );
	fprintf(stderr,"\n");
#endif

	tc_encode_base64( PGPPeekContextMemoryMgr(context), 
		&ticket_stub_b64, &tsize, 
		dhBuf(dhExchange), dhBufSize(dhExchange) );

	makeAuthReq( context, licenseNumber, customerName, companyName, 
		ln_cust_comp_b64 );

	err = parseHttpUrl( url, &addr, &port, host_port, resource );
	if( IsPGPError(err) )  {
		dhFree(dhExchange);
		return err;
	}

	if( IsntPGPError(err) )
		err = createSocket( addr, port, &socket );

	postParams[0] = '\0';
	addFormUrlEncodedParam( "r", tok_ticket, postParams );
	addFormUrlEncodedParam( "group", "0", postParams );

	if( IsntPGPError(err) )
		err = roundTrip( socket, host_port, resource, FALSE, postParams, out, &httpError, &remotePgpError );

	if( httpError == 200 && IsntPGPError(err) && IsntPGPError(remotePgpError) )  {
		err = parseParams( out, ticket_b64, scookie_b64, NULL, NULL, NULL, NULL, NULL );
	}
	else {
		ticket_b64[0] = scookie_b64[0] = '\0';
		if( httpError )  {
#if PGP_DEBUG_PRINT
			fprintf( stderr, "HTTP communication with %s returned %d error code in round 1\n", url, httpError );
#endif
			if( IsPGPError(remotePgpError) )
				err = remotePgpError;
			else
				err = kPGPError_NetworkOpFailed;
		}
	}
	
	if( IsntPGPError(err) ) {
		if( *ticket_b64 == '\0' || *scookie_b64 == '\0' )  
			err = kPGPError_BadParams;
	}

#if PGP_DEBUG_PRINT
	if( IsntPGPError(err) )  {
		fprintf( stderr, "Received (Phase 1):\n" );
		fprintf( stderr, "ticket=%s\n", ticket_b64 );
		fprintf( stderr, "scookie=%s\n", scookie_b64 );
	}
#endif

	if( IsntPGPError(err) )  {
		PGPByte *ticket_bin = NULL;
		PGPSize ticket_bin_size;
		PGPByte *scookie_bin_p=NULL;
		PGPInt32 paddingSize;

		PGPByte ln_cust_comp_b64_encr[kPGPLANet_SendSize];

		PGPUInt32 i;

		tc_decode_base64( PGPPeekContextMemoryMgr(context), 
			&ticket_bin, &ticket_bin_size, ticket_b64 );

		if( ticket_bin )
			err = dhImportGY( dhExchange, ticket_bin, ticket_bin_size );

		if( ticket_bin )
			PGPFreeData(ticket_bin);

		/* prepare secure ln */
		dhGenerate2( dhExchange );

		PGPNewSymmetricCipherContext( context, kPGPCipherAlgorithm_3DES, &symmRef );
		err = PGPGetSymmetricCipherSizes( symmRef, NULL, &cipherBlockSize );
		pgpAssert( cipherBlockSize <= sizeof(IV) );

		/* get (part of) binary secure cookie and put it in IV */
		tc_decode_base64( PGPPeekContextMemoryMgr(context), 
			&scookie_bin_p, &tsize, scookie_b64 );
		if( scookie_bin_p )  {
			pgpCopyMemory( scookie_bin_p, IV, cipherBlockSize );
			PGPFreeData(scookie_bin_p);
		}

		err = PGPNewCBCContext( symmRef, &cbcContext );
		symmRef = kInvalidPGPSymmetricCipherContextRef;
		

		err = PGPInitCBC( cbcContext, dhBuf(dhExchange), IV );

		paddingSize = pkcs5Padding( ln_cust_comp_b64, cipherBlockSize );

		/* do an encryption, check the result */
		for( i = 0; i < strlen(ln_cust_comp_b64)+1 + paddingSize; i += cipherBlockSize )
		{
			err = PGPCBCEncrypt( cbcContext, ln_cust_comp_b64 + i, cipherBlockSize, ln_cust_comp_b64_encr + i );

			if( IsPGPError( err ) )
				break;
		}

		tc_encode_base64( PGPPeekContextMemoryMgr(context), 
			&ln_cust_comp_b64_encr_b64, &tsize, 
			ln_cust_comp_b64_encr, i );	/* multiple of block size */

	}

	postParams[0] = '\0';
	/// XXX check parameters size -- what if scookie was huge??? XXX
	addFormUrlEncodedParam( "r", "activate", postParams );
	addFormUrlEncodedParam( "protected", "yes", postParams );
	addFormUrlEncodedParam( tok_scookie, scookie_b64, postParams );
	addFormUrlEncodedParam( tok_ticket_stub, ticket_stub_b64, postParams );
	
	addFormUrlEncodedParam( "authorize_request", ln_cust_comp_b64_encr_b64, postParams );

	if( ticket_stub_b64 != NULL )
		PGPFreeData( ticket_stub_b64 );

	if( ln_cust_comp_b64_encr_b64  != NULL )
		PGPFreeData( ln_cust_comp_b64_encr_b64  );

	if( IsntPGPError(err) )
		err = roundTrip( socket, host_port, resource, TRUE, postParams, out, &httpError, &remotePgpError );

	if( IsntPGPError(err) )  {
		if( IsPGPError(remotePgpError) )
			err = remotePgpError;

		if( httpError<200 || httpError>=300)  {
#if PGP_DEBUG_PRINT
			fprintf( stderr, 
				"HTTP communication with %s returned %d HTTP code and %d remote PGPError in round 2\n", 
				url, httpError, remotePgpError );
#endif
			if( IsntPGPError(err) )
				err = kPGPError_NetworkOpFailed;
		}
		else  if( httpError==204 ) {
#if PGP_DEBUG_PRINT
			fprintf( stderr, "HTTP LA server said that there is no information to return in round 2. "
				"This means that the server software refused LA (remote PGPError %d)\n", remotePgpError );
#endif
			if( IsntPGPError(err) )
				err = kPGPError_NetLARefused;
		}
	}

	if( IsntPGPError(err)  )  {
		PGPByte la[kPGPLANet_ReceiveSize];
		PGPByte *la_encr = NULL;
		PGPSize la_encr_size;
		PGPUInt32 i;

		parseParams( out, NULL, NULL, NULL, NULL, NULL, la, NULL );

		if( la[0] != '\0' )  {
			tc_decode_base64( PGPPeekContextMemoryMgr(context), 
				&la_encr, &la_encr_size, la );

			err = PGPInitCBC( cbcContext, dhBuf(dhExchange), IV );

			for( i = 0; i < la_encr_size; i += cipherBlockSize )
			{
				err = PGPCBCDecrypt( cbcContext, la_encr + i, cipherBlockSize, la + i );
				if( IsPGPError( err ) )
					break;
			}

			// TODO: check PKCS5 padding 

			err = PGPLAImportBase64( context, la, buffer );
		}
		else {
			err = kPGPError_NetLARefused;	// We got HTTP OK, but could not parse data
											// this is an unidentified server error
		}
	}

	if( cbcContext != NULL )
		(void) PGPFreeCBCContext( cbcContext );

	if( PGPSymmetricCipherContextRefIsValid( symmRef ) )
		(void)PGPFreeSymmetricCipherContext( symmRef );

	if( dhExchange )
		dhFree( dhExchange );

	if( socket != kInvalidPGPSocketRef )
		PGPCloseSocket(socket);

	return err;
}

⌨️ 快捷键说明

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