📄 sess_attr.c
字号:
value, attribute );
if( cryptStatusError( status ) )
return( status );
}
/* Add the private key and increment its reference count */
krnlSendNotifier( value, IMESSAGE_INCREFCOUNT );
sessionInfoPtr->privateKey = value;
return( CRYPT_OK );
}
case CRYPT_SESSINFO_KEYSET:
{
int type;
/* Make sure that it's either a certificate store (rather than
just a generic keyset) if required, or specifically not a
certificate store if not required. This is to prevent a
session running with unnecessary privileges, we should only
be using a certificate store if it's actually required. The
checking is already performed by the kernel, but we do it
again here just to be safe */
status = krnlSendMessage( value, IMESSAGE_GETATTRIBUTE, &type,
CRYPT_IATTRIBUTE_SUBTYPE );
if( cryptStatusError( status ) )
return( CRYPT_ARGERROR_NUM1 );
if( sessionInfoPtr->serverReqAttrFlags & SESSION_NEEDS_CERTSTORE )
{
if( type != SUBTYPE_KEYSET_DBMS_STORE )
return( CRYPT_ARGERROR_NUM1 );
}
else
{
if( type != SUBTYPE_KEYSET_DBMS )
return( CRYPT_ARGERROR_NUM1 );
}
/* Add the keyset and increment its reference count */
krnlSendNotifier( value, IMESSAGE_INCREFCOUNT );
sessionInfoPtr->cryptKeyset = value;
return( CRYPT_OK );
}
case CRYPT_SESSINFO_AUTHRESPONSE:
sessionInfoPtr->authResponse = value;
return( CRYPT_OK );
case CRYPT_SESSINFO_SESSION:
/* If there's already a host or network socket specified we
can't set a transport session as well */
if( findSessionInfo( sessionInfoPtr->attributeList,
CRYPT_SESSINFO_SERVER_NAME ) != NULL )
return( exitErrorInited( sessionInfoPtr,
CRYPT_SESSINFO_SERVER_NAME ) );
if( sessionInfoPtr->networkSocket != CRYPT_ERROR )
return( exitErrorInited( sessionInfoPtr,
CRYPT_SESSINFO_NETWORKSOCKET ) );
/* Add the transport mechanism and increment its reference
count */
krnlSendNotifier( value, IMESSAGE_INCREFCOUNT );
sessionInfoPtr->transportSession = value;
return( CRYPT_OK );
case CRYPT_SESSINFO_NETWORKSOCKET:
{
NET_CONNECT_INFO connectInfo;
STREAM stream;
/* If there's already a host or session specified we can't set a
network socket as well */
if( findSessionInfo( sessionInfoPtr->attributeList,
CRYPT_SESSINFO_SERVER_NAME ) != NULL )
return( exitErrorInited( sessionInfoPtr,
CRYPT_SESSINFO_SERVER_NAME ) );
if( sessionInfoPtr->transportSession != CRYPT_ERROR )
return( exitErrorInited( sessionInfoPtr,
CRYPT_SESSINFO_SESSION ) );
/* Create a dummy network stream to make sure that the network
socket is OK */
initNetConnectInfo( &connectInfo, sessionInfoPtr->ownerHandle,
sessionInfoPtr->readTimeout,
sessionInfoPtr->connectTimeout,
NET_OPTION_NETWORKSOCKET_DUMMY );
connectInfo.networkSocket = value;
status = sNetConnect( &stream, STREAM_PROTOCOL_TCPIP,
&connectInfo, &sessionInfoPtr->errorInfo );
if( cryptStatusError( status ) )
return( status );
sNetDisconnect( &stream );
/* Add the network socket */
sessionInfoPtr->networkSocket = value;
return( CRYPT_OK );
}
}
retIntError();
}
/* Set a string attribute */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int setSessionAttributeS( INOUT SESSION_INFO *sessionInfoPtr,
IN_BUFFER( dataLength ) const void *data,
IN_LENGTH const int dataLength,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
{
assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
assert( isReadPtr( data, dataLength ) );
/* If we're in the middle of a paired-attribute add, make sure that the
conditions under which it's occurring are valid */
if( sessionInfoPtr->lastAddedAttributeID != CRYPT_ATTRIBUTE_NONE )
{
switch( sessionInfoPtr->lastAddedAttributeID )
{
case CRYPT_SESSINFO_USERNAME:
/* Username must be followed by a password */
if( attribute != CRYPT_SESSINFO_PASSWORD )
return( CRYPT_ARGERROR_VALUE );
break;
default:
retIntError();
}
}
/* Handle the various information types */
switch( attribute )
{
case CRYPT_OPTION_NET_SOCKS_SERVER:
case CRYPT_OPTION_NET_SOCKS_USERNAME:
case CRYPT_OPTION_NET_HTTP_PROXY:
/* These aren't implemented on a per-session level yet since
they're almost never used */
return( CRYPT_ARGERROR_VALUE );
case CRYPT_SESSINFO_USERNAME:
case CRYPT_SESSINFO_PASSWORD:
{
int flags = isServer( sessionInfoPtr ) ? \
ATTR_FLAG_MULTIVALUED : ATTR_FLAG_NONE;
int status;
REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_TEXTSIZE );
/* If this is a client session we can only have a single
instance of this attribute */
if( !isServer( sessionInfoPtr ) && \
findSessionInfo( sessionInfoPtr->attributeList,
attribute ) != NULL )
return( exitErrorInited( sessionInfoPtr, attribute ) );
/* If it's a username, make sure that it doesn't duplicate an
existing one */
if( attribute == CRYPT_SESSINFO_USERNAME )
{
if( findSessionInfoEx( sessionInfoPtr->attributeList,
attribute, data, dataLength ) != NULL )
return( exitError( sessionInfoPtr, attribute,
CRYPT_ERRTYPE_ATTR_PRESENT,
CRYPT_ERROR_DUPLICATE ) );
}
else
{
/* It's a password, make sure that there's an associated
username to go with it. There are two approaches that
we can take here, the first simply requires that the
current cursor position is a username, implying that
the last-added attribute was a username. The other is
to try and move the cursor to the last username in the
attribute list and check that the next attribute isn't
a password and then add it there, however this is doing
a bit too much behind the user's back, is somewhat
difficult to back out of, and leads to exceptions to
exceptions, so we keep it simple and only allow passwords
to be added if there's an immediately preceding
username */
if( sessionInfoPtr->lastAddedAttributeID != CRYPT_SESSINFO_USERNAME )
return( exitErrorNotInited( sessionInfoPtr,
CRYPT_SESSINFO_USERNAME ) );
}
/* If it could be an encoded PKI value, check its validity */
if( dataLength >= 15 && isPKIUserValue( data, dataLength ) )
{
BYTE decodedValue[ CRYPT_MAX_TEXTSIZE + 8 ];
int decodedValueLen;
/* It's an encoded value, make sure that it's in order */
status = decodePKIUserValue( decodedValue,
CRYPT_MAX_TEXTSIZE,
&decodedValueLen, data,
dataLength );
zeroise( decodedValue, CRYPT_MAX_TEXTSIZE );
if( cryptStatusError( status ) )
return( status );
flags = ATTR_FLAG_ENCODEDVALUE;
}
/* Remember the value */
status = addSessionInfoEx( &sessionInfoPtr->attributeList,
attribute, data, dataLength, flags );
if( cryptStatusError( status ) )
return( status );
sessionInfoPtr->lastAddedAttributeID = \
( attribute == CRYPT_SESSINFO_USERNAME ) ? \
CRYPT_SESSINFO_USERNAME : CRYPT_ATTRIBUTE_NONE;
return( CRYPT_OK );
}
case CRYPT_SESSINFO_SERVER_FINGERPRINT:
/* Remember the value */
return( addSessionInfo( &sessionInfoPtr->attributeList,
attribute, data, dataLength ) );
case CRYPT_SESSINFO_SERVER_NAME:
return( addUrl( sessionInfoPtr, data, dataLength ) );
}
retIntError();
}
/****************************************************************************
* *
* Delete Attributes *
* *
****************************************************************************/
/* Delete an attribute */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int deleteSessionAttribute( INOUT SESSION_INFO *sessionInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
{
const ATTRIBUTE_LIST *attributeListPtr;
assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
REQUIRES( isAttribute( attribute ) || \
isInternalAttribute( attribute ) );
/* Handle the various information types */
switch( attribute )
{
case CRYPT_OPTION_NET_CONNECTTIMEOUT:
if( sessionInfoPtr->connectTimeout == CRYPT_ERROR )
return( exitErrorNotFound( sessionInfoPtr,
CRYPT_OPTION_NET_CONNECTTIMEOUT ) );
sessionInfoPtr->connectTimeout = CRYPT_ERROR;
return( CRYPT_OK );
case CRYPT_OPTION_NET_READTIMEOUT:
if( sessionInfoPtr->readTimeout == CRYPT_ERROR )
return( exitErrorNotFound( sessionInfoPtr,
CRYPT_OPTION_NET_READTIMEOUT ) );
sessionInfoPtr->readTimeout = CRYPT_ERROR;
return( CRYPT_OK );
case CRYPT_OPTION_NET_WRITETIMEOUT:
if( sessionInfoPtr->writeTimeout == CRYPT_ERROR )
return( exitErrorNotFound( sessionInfoPtr,
CRYPT_OPTION_NET_WRITETIMEOUT ) );
sessionInfoPtr->writeTimeout = CRYPT_ERROR;
return( CRYPT_OK );
case CRYPT_SESSINFO_USERNAME:
case CRYPT_SESSINFO_PASSWORD:
case CRYPT_SESSINFO_SERVER_NAME:
case CRYPT_SESSINFO_SERVER_PORT:
/* Make sure that the attribute to delete is actually present */
attributeListPtr = \
findSessionInfo( sessionInfoPtr->attributeList, attribute );
if( attributeListPtr == NULL )
return( exitErrorNotFound( sessionInfoPtr, attribute ) );
/* If we're in the middle of a paired-attribute add and the
delete affects the paired attribute, delete it. This can
get quite complex because the user could (for example) add
a { username, password } pair, then add a second username
(but not password), and then delete the first password, which
will reset the lastAddedAttributeID, leaving an orphaned
password followed by an orphaned username. There isn't any
easy way to fix this short of forcing some form of group
delete of paired attributes, but this gets too complicated
both to implement and to explain to the user in an error
status. What we do here is handle the simple case and let
the pre-session-activation sanity check catch situations
where the user's gone out of their way to be difficult */
if( sessionInfoPtr->lastAddedAttributeID == attribute )
sessionInfoPtr->lastAddedAttributeID = CRYPT_ATTRIBUTE_NONE;
/* Delete the attribute */
deleteSessionInfo( &sessionInfoPtr->attributeList,
&sessionInfoPtr->attributeListCurrent,
( ATTRIBUTE_LIST * ) attributeListPtr );
return( CRYPT_OK );
case CRYPT_SESSINFO_REQUEST:
if( sessionInfoPtr->iCertRequest == CRYPT_ERROR )
return( exitErrorNotFound( sessionInfoPtr,
CRYPT_SESSINFO_REQUEST ) );
krnlSendNotifier( sessionInfoPtr->iCertRequest,
IMESSAGE_DECREFCOUNT );
sessionInfoPtr->iCertRequest = CRYPT_ERROR;
return( CRYPT_OK );
case CRYPT_SESSINFO_TSP_MSGIMPRINT:
if( sessionInfoPtr->sessionTSP->imprintAlgo == CRYPT_ALGO_NONE || \
sessionInfoPtr->sessionTSP->imprintSize <= 0 )
return( exitErrorNotFound( sessionInfoPtr,
CRYPT_SESSINFO_TSP_MSGIMPRINT ) );
sessionInfoPtr->sessionTSP->imprintAlgo = CRYPT_ALGO_NONE;
sessionInfoPtr->sessionTSP->imprintSize = 0;
return( CRYPT_OK );
}
retIntError();
}
#endif /* USE_SESSIONS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -