📄 sess_attr.c
字号:
/****************************************************************************
* *
* cryptlib Session Attribute Routines *
* Copyright Peter Gutmann 1998-2007 *
* *
****************************************************************************/
#include <stdio.h>
#include "crypt.h"
#ifdef INC_ALL
#include "session.h"
#else
#include "session/session.h"
#endif /* Compiler-specific includes */
#ifdef USE_SESSIONS
/****************************************************************************
* *
* Utility Functions *
* *
****************************************************************************/
/* Exit after setting extended error information */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int exitError( INOUT SESSION_INFO *sessionInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus,
IN_ENUM( CRYPT_ERRTYPE ) const CRYPT_ERRTYPE_TYPE errorType,
IN_ERROR const int status )
{
assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
REQUIRES( isAttribute( errorLocus ) || \
isInternalAttribute( errorLocus ) );
REQUIRES( errorType > CRYPT_ERRTYPE_NONE && \
errorType < CRYPT_ERRTYPE_LAST );
REQUIRES( cryptStatusError( status ) );
setErrorInfo( sessionInfoPtr, errorLocus, errorType );
return( status );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int exitErrorInited( INOUT SESSION_INFO *sessionInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
{
assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
REQUIRES( isAttribute( errorLocus ) || \
isInternalAttribute( errorLocus ) );
return( exitError( sessionInfoPtr, errorLocus, CRYPT_ERRTYPE_ATTR_PRESENT,
CRYPT_ERROR_INITED ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int exitErrorNotInited( INOUT SESSION_INFO *sessionInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
{
assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
REQUIRES( isAttribute( errorLocus ) || \
isInternalAttribute( errorLocus ) );
return( exitError( sessionInfoPtr, errorLocus, CRYPT_ERRTYPE_ATTR_ABSENT,
CRYPT_ERROR_NOTINITED ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int exitErrorNotFound( INOUT SESSION_INFO *sessionInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
{
assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
REQUIRES( isAttribute( errorLocus ) || \
isInternalAttribute( errorLocus ) );
return( exitError( sessionInfoPtr, errorLocus, CRYPT_ERRTYPE_ATTR_ABSENT,
CRYPT_ERROR_NOTFOUND ) );
}
/* Add the contents of an encoded URL to a session. This requires parsing
the individual session attribute components out of the URL and then
adding each one in turn */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int addUrl( INOUT SESSION_INFO *sessionInfoPtr,
IN_BUFFER( urlLength ) const void *url,
IN_LENGTH_DNS const int urlLength )
{
const PROTOCOL_INFO *protocolInfoPtr = sessionInfoPtr->protocolInfo;
URL_INFO urlInfo;
int status;
assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
assert( isReadPtr( url, urlLength ) );
REQUIRES( urlLength > 0 && urlLength < MAX_URL_SIZE );
/* If there's already a transport session or network socket specified,
we can't set a server name as well */
if( sessionInfoPtr->transportSession != CRYPT_ERROR )
return( exitErrorInited( sessionInfoPtr, CRYPT_SESSINFO_SESSION ) );
if( sessionInfoPtr->networkSocket != CRYPT_ERROR )
return( exitErrorInited( sessionInfoPtr,
CRYPT_SESSINFO_NETWORKSOCKET ) );
/* Parse the server name. The PKI protocols all use HTTP as their
substrate so if it's not SSH or SSL/TLS we require HTTP. For TSP
and CMP the user can also specify the braindamaged "TCP transport"
protocol but luckily this seems to have mostly sunk without trace,
other portions of the session-handling code also discourage its
use so we don't encourate it here */
status = sNetParseURL( &urlInfo, url, urlLength,
( sessionInfoPtr->type == CRYPT_SESSION_SSH ) ? \
URL_TYPE_SSH : \
( sessionInfoPtr->type == CRYPT_SESSION_SSL ) ? \
URL_TYPE_HTTPS : URL_TYPE_HTTP );
if( cryptStatusError( status ) )
return( exitError( sessionInfoPtr, CRYPT_SESSINFO_SERVER_NAME,
CRYPT_ERRTYPE_ATTR_VALUE, CRYPT_ARGERROR_STR1 ) );
/* We can only use autodetection with PKI services */
if( !strCompare( url, "[Autodetect]", urlLength ) && \
!protocolInfoPtr->isReqResp )
return( exitError( sessionInfoPtr, CRYPT_SESSINFO_SERVER_NAME,
CRYPT_ERRTYPE_ATTR_VALUE, CRYPT_ARGERROR_STR1 ) );
/* Remember the server name */
if( urlInfo.hostLen + urlInfo.locationLen >= MAX_URL_SIZE )
{
/* This should never happen since the overall URL size has to be
less than MAX_URL_SIZE */
assert( INTERNAL_ERROR );
return( exitError( sessionInfoPtr, CRYPT_SESSINFO_SERVER_NAME,
CRYPT_ERRTYPE_ATTR_VALUE, CRYPT_ARGERROR_STR1 ) );
}
if( urlInfo.locationLen <= 0 )
{
status = addSessionInfo( &sessionInfoPtr->attributeList,
CRYPT_SESSINFO_SERVER_NAME,
urlInfo.host, urlInfo.hostLen );
}
else
{
char urlBuffer[ MAX_URL_SIZE + 8 ];
memcpy( urlBuffer, urlInfo.host, urlInfo.hostLen );
memcpy( urlBuffer + urlInfo.hostLen, urlInfo.location,
urlInfo.locationLen );
status = addSessionInfo( &sessionInfoPtr->attributeList,
CRYPT_SESSINFO_SERVER_NAME, urlBuffer,
urlInfo.hostLen + urlInfo.locationLen );
}
if( cryptStatusError( status ) )
return( exitError( sessionInfoPtr, CRYPT_SESSINFO_SERVER_NAME,
CRYPT_ERRTYPE_ATTR_VALUE, CRYPT_ARGERROR_STR1 ) );
/* If there's a port or user name specified in the URL, remember them.
We have to add the user name after we add any other attributes
because it's paired with a password, so adding the user name and then
following it with something that isn't a password will cause an error
return */
if( urlInfo.port > 0 )
{
( void ) krnlSendMessage( sessionInfoPtr->objectHandle,
IMESSAGE_DELETEATTRIBUTE, NULL,
CRYPT_SESSINFO_SERVER_PORT );
status = krnlSendMessage( sessionInfoPtr->objectHandle,
IMESSAGE_SETATTRIBUTE, &urlInfo.port,
CRYPT_SESSINFO_SERVER_PORT );
}
if( cryptStatusOK( status ) && urlInfo.userInfoLen > 0 )
{
MESSAGE_DATA userInfoMsgData;
( void ) krnlSendMessage( sessionInfoPtr->objectHandle,
IMESSAGE_DELETEATTRIBUTE, NULL,
CRYPT_SESSINFO_USERNAME );
setMessageData( &userInfoMsgData, ( void * ) urlInfo.userInfo,
urlInfo.userInfoLen );
status = krnlSendMessage( sessionInfoPtr->objectHandle,
IMESSAGE_SETATTRIBUTE_S, &userInfoMsgData,
CRYPT_SESSINFO_USERNAME );
}
if( cryptStatusError( status ) )
return( exitError( sessionInfoPtr, CRYPT_SESSINFO_SERVER_NAME,
CRYPT_ERRTYPE_ATTR_VALUE, CRYPT_ARGERROR_STR1 ) );
/* Remember the transport type */
if( protocolInfoPtr->altProtocolInfo != NULL && \
urlInfo.schemaLen == \
protocolInfoPtr->altProtocolInfo->uriTypeLen && \
!strCompare( urlInfo.schema,
protocolInfoPtr->altProtocolInfo->uriType,
protocolInfoPtr->altProtocolInfo->uriTypeLen ) )
{
/* The caller has specified the use of the alternate transport
protocol type, switch to that instead of HTTP */
sessionInfoPtr->flags &= ~protocolInfoPtr->altProtocolInfo->oldFlagsMask;
sessionInfoPtr->flags |= protocolInfoPtr->altProtocolInfo->newFlags;
}
else
{
if( sessionInfoPtr->protocolInfo->flags & SESSION_ISHTTPTRANSPORT )
{
sessionInfoPtr->flags &= ~SESSION_USEALTTRANSPORT;
sessionInfoPtr->flags |= SESSION_ISHTTPTRANSPORT;
}
}
return( CRYPT_OK );
}
/****************************************************************************
* *
* Get Attributes *
* *
****************************************************************************/
/* Get a numeric/boolean attribute */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int getSessionAttribute( INOUT SESSION_INFO *sessionInfoPtr,
OUT_INT_Z int *valuePtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
{
assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
assert( isWritePtr( valuePtr, sizeof( int ) ) );
REQUIRES( isAttribute( attribute ) || \
isInternalAttribute( attribute ) );
/* Clear return value */
*valuePtr = 0;
/* Handle the various information types */
switch( attribute )
{
case CRYPT_ATTRIBUTE_CURRENT:
case CRYPT_ATTRIBUTE_CURRENT_GROUP:
{
int value, status;
status = getSessionAttributeCursor( sessionInfoPtr->attributeList,
sessionInfoPtr->attributeListCurrent,
attribute, &value );
if( status == OK_SPECIAL )
{
/* The attribute list wasn't initialised yet, initialise it
now */
sessionInfoPtr->attributeListCurrent = \
sessionInfoPtr->attributeList;
}
else
{
if( cryptStatusError( status ) )
return( exitError( sessionInfoPtr, attribute,
CRYPT_ERRTYPE_ATTR_ABSENT, status ) );
}
*valuePtr = value;
return( CRYPT_OK );
}
case CRYPT_OPTION_NET_CONNECTTIMEOUT:
if( sessionInfoPtr->connectTimeout == CRYPT_ERROR )
return( exitErrorNotInited( sessionInfoPtr,
CRYPT_OPTION_NET_CONNECTTIMEOUT ) );
*valuePtr = sessionInfoPtr->connectTimeout;
return( CRYPT_OK );
case CRYPT_OPTION_NET_READTIMEOUT:
if( sessionInfoPtr->readTimeout == CRYPT_ERROR )
return( exitErrorNotInited( sessionInfoPtr,
CRYPT_OPTION_NET_READTIMEOUT ) );
*valuePtr = sessionInfoPtr->readTimeout;
return( CRYPT_OK );
case CRYPT_OPTION_NET_WRITETIMEOUT:
if( sessionInfoPtr->writeTimeout == CRYPT_ERROR )
return( exitErrorNotInited( sessionInfoPtr,
CRYPT_OPTION_NET_WRITETIMEOUT ) );
*valuePtr = sessionInfoPtr->writeTimeout;
return( CRYPT_OK );
case CRYPT_ATTRIBUTE_ERRORTYPE:
*valuePtr = sessionInfoPtr->errorType;
return( CRYPT_OK );
case CRYPT_ATTRIBUTE_ERRORLOCUS:
*valuePtr = sessionInfoPtr->errorLocus;
return( CRYPT_OK );
case CRYPT_ATTRIBUTE_BUFFERSIZE:
*valuePtr = sessionInfoPtr->receiveBufSize;
return( CRYPT_OK );
case CRYPT_ATTRIBUTE_INT_ERRORCODE:
{
ERROR_INFO *errorInfo = &sessionInfoPtr->errorInfo;
*valuePtr = errorInfo ->errorCode;
return( CRYPT_OK );
}
case CRYPT_SESSINFO_ACTIVE:
/* Only secure transport sessions can be persistently active,
request/response sessions are only active while the
transaction is in progress. Note that this differs from the
connection-active state, which records the fact that there's
a network-level connection established but no messages or
secure session active across it. See the comment in
setSessionAttribute() for more on this */
*valuePtr = sessionInfoPtr->iCryptInContext != CRYPT_ERROR && \
( sessionInfoPtr->flags & SESSION_ISOPEN ) ? \
TRUE : FALSE;
return( CRYPT_OK );
case CRYPT_SESSINFO_CONNECTIONACTIVE:
*valuePtr = ( sessionInfoPtr->flags & SESSION_ISOPEN ) ? \
TRUE : FALSE;
return( CRYPT_OK );
case CRYPT_SESSINFO_SERVER_PORT:
case CRYPT_SESSINFO_CLIENT_PORT:
{
const ATTRIBUTE_LIST *attributeListPtr = \
findSessionInfo( sessionInfoPtr->attributeList,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -