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

📄 str_net.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 3 页
字号:
		}

	/* Wait for any async network driver binding to complete */
	waitSemaphore( SEMAPHORE_DRIVERBIND );

	/* Make sure that the network interface has been initialised */
	if( !stream->transportOKFunction() )
		{
		/* Provide more information on the nature of the problem */
		strcpy( errorMessage, "cryptlib network interface not initialised" );

		/* Clean up.  We can't use cleanupStream() at this point because the
		   stream hasn't been fully initialised yet */
		if( stream->host != NULL )
			clFree( "completeConnect", stream->host );
		zeroise( stream, sizeof( STREAM ) );
		return( CRYPT_ERROR_NOTINITED );
		}

	/* Allocate room for the I/O buffers and error messages returned from the 
	   lower-level networking code */
	if( ( stream->errorMessage = clAlloc( "completeConnect", \
										  MAX_ERRMSG_SIZE + 1 ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	if( useTransportBuffering )
		{
		if( ( stream->buffer = clAlloc( "completeConnect", \
										NETWORK_BUFFER_SIZE ) ) != NULL )
			{
			stream->bufSize = NETWORK_BUFFER_SIZE;
			if( ( stream->writeBuffer = \
					clAlloc( "completeConnect", NETWORK_BUFFER_SIZE ) ) != NULL )
				stream->writeBufSize = NETWORK_BUFFER_SIZE;
			}
		if( stream->writeBufSize <= 0 )
			{
			cleanupStream( stream, FALSE );
			return( CRYPT_ERROR_MEMORY );
			}
		}
	memset( stream->errorMessage, 0, MAX_ERRMSG_SIZE + 1 );

	/* If we're not using an already-active network socket supplied by the 
	   user, activate the connection */
	if( !( stream->flags & STREAM_NFLAG_USERSOCKET ) )
		{
		if( proxyURL != NULL )
			{
			URL_INFO urlInfo;

			/* We're going via a proxy, open the connection to the proxy 
			   rather than directly to the target system.  Since this is an
			   HTTP proxy, we specify the default port as port 80 */
			status = parseURL( &urlInfo, proxyURL, strlen( proxyURL ), 80 );
			if( cryptStatusError( status ) )
				{
				/* The proxy URL was invalid, provide more information for 
				   the caller */
				status = CRYPT_ERROR_OPEN;
				stream->errorCode = CRYPT_ERROR_BADDATA;
				strcpy( stream->errorMessage, "Invalid HTTP proxy URL" );
				}
			else
				{
				char urlBuffer[ MAX_DNS_SIZE + 1 ];

				memcpy( urlBuffer, urlInfo.host, urlInfo.hostLen );
				urlBuffer[ urlInfo.hostLen ] = '\0';
				status = stream->transportConnectFunction( stream, urlBuffer,
														   urlInfo.port );
				}
			}
		else
			status = stream->transportConnectFunction( stream, stream->host,
													   stream->port );
		}
	else
		/* If it's a dummy open to check parameters that can't be validated 
		   at a higher level, pass the info on down to the low-level 
		   checking routines */
		if( options == NET_OPTION_NETWORKSOCKET_DUMMY )
			status = stream->transportCheckFunction( stream );
	if( cryptStatusError( status ) )
		{
		/* Copy back the error information to the caller */
		*errorCode = stream->errorCode;
		strcpy( errorMessage, stream->errorMessage );

		/* Clean up */
		cleanupStream( stream, FALSE );
		return( status );
		}
	if( options == NET_OPTION_NETWORKSOCKET_DUMMY )
		/* If it's a dummy open to check parameters, don't do anything 
		   further */
		return( CRYPT_OK );

	/* We're connected, update the stream timeout value to contain the 
	   network I/O timeout rather than the connect timeout.  We use sioctl() 
	   rather than setting it directly to ensure that it gets reflected down 
	   to any underlying transport-layer objects */
	if( netTimeout != CRYPT_ERROR )
		timeout = netTimeout;
	else
		if( cryptStatusError( \
				krnlSendMessage( iUserObject, IMESSAGE_GETATTRIBUTE, 
								 &timeout, CRYPT_OPTION_NET_TIMEOUT ) ) )
			timeout = 30;
	sioctl( stream, STREAM_IOCTL_TIMEOUT, NULL, timeout );

	return( CRYPT_OK );
	}

/* Open and close a network connection.  This parses a location string
   (usually a URL) into <scheme>://<host>[:<port>]/<path>[?<query>]
   components and opens a connection to the host for non-stateless
   protocols */

int sNetConnect( STREAM *stream, const STREAM_PROTOCOL_TYPE protocol,
				 const NET_CONNECT_INFO *connectInfo, char *errorMessage, 
				 int *errorCode )
	{
	URL_INFO urlInfo;
	char proxyUrlBuffer[ MAX_DNS_SIZE + 1 ], *proxyURL = NULL;
	int timeout, status;

	assert( isWritePtr( stream, STREAM ) );
	assert( protocol == STREAM_PROTOCOL_TCPIP || \
			protocol == STREAM_PROTOCOL_HTTP || \
			protocol == STREAM_PROTOCOL_HTTP_TRANSACTION || \
			protocol == STREAM_PROTOCOL_CMP );
	assert( isReadPtr( connectInfo, NET_CONNECT_INFO ) );
	assert( errorMessage != NULL && errorCode != NULL );
	assert( connectInfo->options != NET_OPTION_HOSTNAME || \
			( connectInfo->options == NET_OPTION_HOSTNAME && \
			  connectInfo->name != NULL && connectInfo->name[ 0 ] && \
			  connectInfo->iCryptSession == CRYPT_ERROR && \
			  connectInfo->networkSocket == CRYPT_ERROR ) );
	assert( connectInfo->options != NET_OPTION_TRANSPORTSESSION || \
			( connectInfo->options == NET_OPTION_TRANSPORTSESSION && \
			  connectInfo->name == NULL && \
			  connectInfo->iCryptSession != CRYPT_ERROR && \
			  connectInfo->networkSocket == CRYPT_ERROR ) );
	assert( ( connectInfo->options != NET_OPTION_NETWORKSOCKET && \
			  connectInfo->options != NET_OPTION_NETWORKSOCKET_DUMMY ) || \
			( ( connectInfo->options == NET_OPTION_NETWORKSOCKET || \
				connectInfo->options == NET_OPTION_NETWORKSOCKET_DUMMY ) && \
			  connectInfo->name == NULL && \
			  connectInfo->iCryptSession == CRYPT_ERROR && \
			  connectInfo->networkSocket != CRYPT_ERROR ) );
	assert( connectInfo->iUserObject >= DEFAULTUSER_OBJECT_HANDLE && 
			connectInfo->iUserObject < MAX_OBJECTS );

	/* Clear the return values */
	*errorMessage = '\0';
	*errorCode = 0;

	/* Initialise the stream structure.  While we're connecting, the stream 
	   timeout is the connect timeout.  Once we've connected it's set to the
	   communication timeout */
	if( connectInfo->connectTimeout != CRYPT_ERROR )
		timeout = connectInfo->connectTimeout;
	else
		if( cryptStatusError( \
				krnlSendMessage( connectInfo->iUserObject, IMESSAGE_GETATTRIBUTE, 
								 &timeout, CRYPT_OPTION_NET_CONNECTTIMEOUT ) ) )
			timeout = 30;
	if( timeout < 5 )
		{
		/* Enforce the same minimum connect timeout as the kernel ACLs */
		assert( NOTREACHED );
		timeout = 5;
		}
	memset( stream, 0, sizeof( STREAM ) );
	stream->type = STREAM_TYPE_NETWORK;
	stream->protocol = protocol;
	stream->timeout = stream->savedTimeout = timeout;
	stream->port = connectInfo->port;
	stream->netSocket = stream->listenSocket = CRYPT_ERROR;
	stream->iTransportSession = CRYPT_ERROR;
	switch( connectInfo->options )
		{
		case NET_OPTION_HOSTNAME:
			/* If we're using standard HTTP then only an HTTP GET is 
			   possible, use of POST requires the HTTP_TRANSACTION variant */
			if( protocol == STREAM_PROTOCOL_HTTP )
				stream->flags = STREAM_FLAG_READONLY;

			/* Parse the URI into its various components */
			status = parseURL( &urlInfo, connectInfo->name, 
						strlen( connectInfo->name ), connectInfo->port );
			if( cryptStatusError( status ) )
				{
				/* There's an error in the URL format, provide more 
				   information to the caller */
				strcpy( errorMessage, "Invalid host name/URL" );
				return( CRYPT_ERROR_OPEN );
				}
			status = copyUrlToStream( stream, &urlInfo );
			if( cryptStatusError( status ) )
				return( status );

			/* If it's going to something other than the local system, check 
			   to see whether we're going through a proxy.  We only use the
			   case-insensitive string compares for the text-format host 
			   names, since the numeric forms don't need this */
			if( ( protocol == STREAM_PROTOCOL_HTTP || \
				  protocol == STREAM_PROTOCOL_HTTP_TRANSACTION ) && \
				( strcmp( stream->host, "127.0.0.1" ) && \
				  strcmp( stream->host, "::1" ) && \
				  strCompareZ( stream->host, "localhost" ) && \
				  strCompare( stream->host, "localhost.", 10 ) ) )	/* Are you local? */
				{
				RESOURCE_DATA msgData;

				/* Check whether there's an HTTP proxy configured */
				setMessageData( &msgData, proxyUrlBuffer, MAX_DNS_SIZE );
				status = krnlSendMessage( connectInfo->iUserObject, 
										  IMESSAGE_GETATTRIBUTE_S, &msgData, 
										  CRYPT_OPTION_NET_HTTP_PROXY );
				if( cryptStatusOK( status ) )
					{
					proxyUrlBuffer[ msgData.length ] = '\0';
					proxyURL = proxyUrlBuffer;
					stream->flags |= STREAM_NFLAG_HTTPPROXY;
					}
				}
			break;

		case NET_OPTION_TRANSPORTSESSION:
			stream->iTransportSession = connectInfo->iCryptSession;
			break;

		case NET_OPTION_NETWORKSOCKET:
		case NET_OPTION_NETWORKSOCKET_DUMMY:
			stream->netSocket = connectInfo->networkSocket;
			stream->flags |= STREAM_NFLAG_USERSOCKET;
			break;

		default:
			assert( NOTREACHED );
			return( CRYPT_ERROR );
		}

	/* Set up access mechanisms and complete the connection */
	return( completeConnect( stream, protocol, connectInfo->options, proxyURL,
							 connectInfo->iUserObject, connectInfo->timeout, 
							 errorMessage, errorCode ) );
	}

int sNetListen( STREAM *stream, const STREAM_PROTOCOL_TYPE protocol,
				const NET_CONNECT_INFO *connectInfo, char *errorMessage,
				int *errorCode )
	{
	URL_INFO urlInfo;
	int timeout;

	assert( isWritePtr( stream, STREAM ) );
	assert( protocol == STREAM_PROTOCOL_TCPIP || \
			protocol == STREAM_PROTOCOL_HTTP_TRANSACTION || \
			protocol == STREAM_PROTOCOL_CMP );
	assert( isReadPtr( connectInfo, NET_CONNECT_INFO ) );
	assert( errorMessage != NULL && errorCode != NULL );
	assert( connectInfo->options != NET_OPTION_HOSTNAME || \
			( connectInfo->options == NET_OPTION_HOSTNAME && \
			  connectInfo->iCryptSession == CRYPT_ERROR && \
			  connectInfo->networkSocket == CRYPT_ERROR ) );
	assert( connectInfo->options != NET_OPTION_TRANSPORTSESSION || \
			( connectInfo->options == NET_OPTION_TRANSPORTSESSION && \
			  connectInfo->name == NULL && \
			  connectInfo->iCryptSession != CRYPT_ERROR && \
			  connectInfo->networkSocket == CRYPT_ERROR ) );
	assert( ( connectInfo->options != NET_OPTION_NETWORKSOCKET && \
			  connectInfo->options != NET_OPTION_NETWORKSOCKET_DUMMY ) || \
			( ( connectInfo->options == NET_OPTION_NETWORKSOCKET || \
				connectInfo->options == NET_OPTION_NETWORKSOCKET_DUMMY ) || \
			  connectInfo->name == NULL && \
			  connectInfo->iCryptSession == CRYPT_ERROR && \
			  connectInfo->networkSocket != CRYPT_ERROR ) );
	assert( connectInfo->iUserObject >= DEFAULTUSER_OBJECT_HANDLE && 
			connectInfo->iUserObject < MAX_OBJECTS );

	/* Clear the return values */
	*errorMessage = '\0';
	*errorCode = 0;

	/* Initialise the stream structure.  While we're connecting, the stream 
	   timeout is the connect timeout.  Once we've connected it's set to the
	   communication timeout */
	if( connectInfo->connectTimeout != CRYPT_ERROR )
		timeout = connectInfo->connectTimeout;
	else
		if( cryptStatusError( \
				krnlSendMessage( connectInfo->iUserObject, IMESSAGE_GETATTRIBUTE, 
								 &timeout, CRYPT_OPTION_NET_CONNECTTIMEOUT ) ) )
			timeout = 30;
	if( timeout < 5 )
		{
		/* Enforce the same minimum connect timeout as the kernel ACLs */
		assert( NOTREACHED );
		timeout = 5;
		}
	memset( stream, 0, sizeof( STREAM ) );
	stream->type = STREAM_TYPE_NETWORK;
	stream->protocol = protocol;
	stream->timeout = INT_MAX - 1;
	stream->savedTimeout = timeout;
	stream->port = connectInfo->port;
	stream->netSocket = stream->listenSocket = CRYPT_ERROR;
	stream->iTransportSession = CRYPT_ERROR;
	stream->flags = STREAM_NFLAG_ISSERVER;
	switch( connectInfo->options )
		{
		case NET_OPTION_HOSTNAME:
			if( connectInfo->name != NULL )
				{
				int status;

				/* Parse the interface URI into its various components */
				status = parseURL( &urlInfo, connectInfo->name, 
							strlen( connectInfo->name ), connectInfo->port );
				if( cryptStatusError( status ) )
					{
					/* There's an error in the format, provide more 
					   information to the caller */
					strcpy( errorMessage, "Invalid interface name" );
					return( CRYPT_ERROR_OPEN );
					}
				status = copyUrlToStream( stream, &urlInfo );
				if( cryptStatusError( status ) )
					return( status );
				}
			break;

		case NET_OPTION_TRANSPORTSESSION:
			stream->iTransportSession = connectInfo->iCryptSession;
			break;

		case NET_OPTION_NETWORKSOCKET:
		case NET_OPTION_NETWORKSOCKET_DUMMY:
			stream->netSocket = connectInfo->networkSocket;
			stream->flags |= STREAM_NFLAG_USERSOCKET;
			break;

		default:
			assert( NOTREACHED );
			return( CRYPT_ERROR );
		}

	/* Set up access mechanisms and complete the connection */
	return( completeConnect( stream, protocol, connectInfo->options, NULL,
							 connectInfo->iUserObject, connectInfo->timeout, 
							 errorMessage, errorCode ) );
	}

int sNetDisconnect( STREAM *stream )
	{
	cleanupStream( stream, TRUE );

	return( CRYPT_OK );
	}

/* Parse a URL into its various components */

int sNetParseURL( URL_INFO *urlInfo, const char *url, const int urlLen )
	{
	return( parseURL( urlInfo, url, urlLen, CRYPT_UNUSED ) );
	}

/* Get extended information about an error status on a network connection */

void sNetGetErrorInfo( STREAM *stream, char *errorString, int *errorCode )
	{
	assert( isReadPtr( stream, STREAM ) );
	assert( stream->type == STREAM_TYPE_NETWORK );

	/* Remember the error code and message.  If we're running over a 
	   cryptlib transport session we have to first pull the info up from the 
	   session */
	if( stream->iTransportSession != CRYPT_ERROR )
		getSessionErrorInfo( stream, CRYPT_OK );
	*errorCode = stream->errorCode;
	strcpy( errorString, stream->errorMessage );
	}

#else

/****************************************************************************
*																			*
*							Network Stream Stubs							*
*																			*
****************************************************************************/

/* If there's no networking support present, we replace the network access
   routines with dummy ones that always return an error */

int sNetConnect( STREAM *stream, const STREAM_PROTOCOL_TYPE protocol,
				 const NET_CONNECT_INFO *connectInfo, char *errorMessage,
				 int *errorCode )
	{
	memset( stream, 0, sizeof( STREAM ) );
	return( CRYPT_ERROR_OPEN );
	}

int sNetListen( STREAM *stream, const STREAM_PROTOCOL_TYPE protocol,
				const NET_CONNECT_INFO *connectInfo, char *errorMessage,
				int *errorCode )
	{
	memset( stream, 0, sizeof( STREAM ) );
	return( CRYPT_ERROR_OPEN );
	}

int sNetDisconnect( STREAM *stream )
	{
	UNUSED( stream );

	return( CRYPT_OK );
	}

int sNetParseURL( URL_INFO *urlInfo, const char *url, const int urlLen )
	{
	memset( urlInfo, 0, sizeof( URL_INFO ) );

	return( CRYPT_ERROR_BADDATA );
	}

void sNetGetErrorInfo( STREAM *stream, char *errorString, int *errorCode )
	{
	UNUSED( stream );

	*errorString = '\0';
	*errorCode = CRYPT_OK;
	}
#endif /* USE_TCP */

⌨️ 快捷键说明

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