123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- #include "ua_securechannel_manager.h"
- #include "util/ua_util.h"
- struct channel_list_entry {
- UA_SecureChannel channel;
- LIST_ENTRY(channel_list_entry) pointers;
- };
- struct UA_SecureChannelManager {
- UA_Int32 maxChannelCount;
- UA_DateTime maxChannelLifetime;
- LIST_HEAD(channel_list, channel_list_entry) channels;
- UA_MessageSecurityMode securityMode;
- UA_String endpointUrl;
- UA_DateTime channelLifeTime;
- UA_Int32 lastChannelId;
- UA_UInt32 lastTokenId;
- };
- UA_Int32 UA_SecureChannelManager_new(UA_SecureChannelManager **cm, UA_UInt32 maxChannelCount,
- UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
- UA_UInt32 startTokenId, UA_String *endpointUrl) {
- UA_alloc((void**)cm,sizeof(UA_SecureChannelManager));
- UA_SecureChannelManager *channelManager = *cm;
- LIST_INIT(&channelManager->channels);
- channelManager->lastChannelId = startChannelId;
- channelManager->lastTokenId = startTokenId;
- UA_String_copy(endpointUrl,&channelManager->endpointUrl);
- channelManager->maxChannelLifetime = tokenLifetime;
- channelManager->maxChannelCount = maxChannelCount;
- return UA_SUCCESS;
- }
- UA_Int32 UA_SecureChannelManager_delete(UA_SecureChannelManager *cm) {
- struct channel_list_entry *entry;
- LIST_FOREACH(entry, &cm->channels, pointers) {
- // deleting a securechannel means closing the connection
- // delete the binaryconnction beforehand. so there is no pointer
- // todo: unbind entry->channel.connection;
- LIST_REMOVE(entry, pointers);
- UA_SecureChannel_deleteMembers(&entry->channel);
- UA_free(entry);
- }
- UA_String_deleteMembers(&cm->endpointUrl);
- UA_free(cm);
- return UA_SUCCESS;
- }
- UA_Int32 UA_SecureChannelManager_open(UA_SecureChannelManager *cm,
- UA_Connection *conn,
- const UA_OpenSecureChannelRequest* request,
- UA_OpenSecureChannelResponse* response) {
- struct channel_list_entry *entry;
- UA_alloc((void**)&entry, sizeof(struct channel_list_entry));
- entry->channel.connection = conn;
- entry->channel.securityToken.channelId = cm->lastChannelId++;
- entry->channel.securityToken.tokenId = cm->lastTokenId++;
- entry->channel.securityToken.createdAt = UA_DateTime_now();
- entry->channel.securityToken.revisedLifetime =
- request->requestedLifetime > cm->maxChannelLifetime ?
- cm->maxChannelLifetime : request->requestedLifetime;
- switch (request->securityMode) {
- case UA_SECURITYMODE_INVALID:
- printf("UA_SecureChannel_processOpenRequest - client demands invalid \n");
- break;
- case UA_SECURITYMODE_NONE:
- UA_ByteString_copy(&request->clientNonce, &entry->channel.clientNonce);
- entry->channel.clientAsymAlgSettings.receiverCertificateThumbprint.data = UA_NULL;
- entry->channel.clientAsymAlgSettings.receiverCertificateThumbprint.length = -1;
- entry->channel.clientAsymAlgSettings.senderCertificate.data = UA_NULL;
- entry->channel.clientAsymAlgSettings.senderCertificate.length = -1;
- break;
- case UA_SECURITYMODE_SIGNANDENCRYPT:
- printf("UA_SecureChannel_processOpenRequest - client demands signed & encrypted \n");
- //TODO check if senderCertificate and ReceiverCertificateThumbprint are present
- break;
- }
- UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None",
- (UA_String*)&entry->channel.serverAsymAlgSettings.securityPolicyUri);
- LIST_INSERT_HEAD(&cm->channels, entry, pointers);
- response->serverProtocolVersion = 0;
- UA_SecureChannel_generateNonce(&entry->channel.serverNonce);
- UA_ByteString_copy(&entry->channel.serverNonce, &response->serverNonce);
- UA_ChannelSecurityToken_copy(&entry->channel.securityToken, &response->securityToken);
-
- return UA_SUCCESS;
- }
- UA_Int32 UA_SecureChannelManager_renew(UA_SecureChannelManager *cm,
- UA_Connection *conn,
- const UA_OpenSecureChannelRequest* request,
- UA_OpenSecureChannelResponse* response) {
- UA_SecureChannel *channel = conn->channel;
- if(channel == UA_NULL)
- return UA_ERROR;
- // TODO write response
- channel->securityToken.createdAt = UA_DateTime_now(); // todo: is wanted?
- channel->securityToken.revisedLifetime = request->requestedLifetime > cm->maxChannelLifetime ?
- cm->maxChannelLifetime : request->requestedLifetime;
- return UA_SUCCESS;
- }
- UA_Int32 UA_SecureChannelManager_get(UA_SecureChannelManager *cm, UA_UInt32 channelId, UA_SecureChannel **channel) {
- struct channel_list_entry *entry;
- LIST_FOREACH(entry, &cm->channels, pointers) {
- if(entry->channel.securityToken.channelId == channelId) {
- *channel = &entry->channel;
- return UA_SUCCESS;
- }
- }
- *channel = UA_NULL;
- return UA_ERROR;
- }
- UA_Int32 UA_SecureChannelManager_close(UA_SecureChannelManager *cm, UA_UInt32 channelId) {
- //TODO lock access
- // TODO: close the binaryconnection if it is still open. So we dö not have stray pointers..
- struct channel_list_entry *entry;
- LIST_FOREACH(entry, &cm->channels, pointers) {
- if(entry->channel.securityToken.channelId == channelId) {
- UA_SecureChannel_deleteMembers(&entry->channel);
- LIST_REMOVE(entry, pointers);
- UA_free(entry);
- return UA_SUCCESS;
- }
- }
- //TODO notify server application that secureChannel has been closed part 6 - §7.1.4
- return UA_ERROR;
- }
|