123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- #include "ua_securechannel_manager.h"
- #include "ua_session.h"
- #include "ua_statuscodes.h"
- UA_StatusCode UA_SecureChannelManager_init(UA_SecureChannelManager *cm, UA_UInt32 maxChannelCount,
- UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
- UA_UInt32 startTokenId) {
- LIST_INIT(&cm->channels);
- cm->lastChannelId = startChannelId;
- cm->lastTokenId = startTokenId;
- cm->maxChannelLifetime = tokenLifetime;
- cm->maxChannelCount = maxChannelCount;
- return UA_STATUSCODE_GOOD;
- }
- void UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager *cm) {
- channel_list_entry *current, *next = LIST_FIRST(&cm->channels);
- while(next) {
- current = next;
- next = LIST_NEXT(current, pointers);
- LIST_REMOVE(current, pointers);
- if(current->channel.session)
- current->channel.session->channel = UA_NULL;
- if(current->channel.connection)
- current->channel.connection->channel = UA_NULL;
- UA_SecureChannel_deleteMembers(¤t->channel);
- UA_free(current);
- }
- }
- UA_StatusCode UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
- const UA_OpenSecureChannelRequest *request,
- UA_OpenSecureChannelResponse *response)
- {
- switch(request->securityMode) {
- case UA_MESSAGESECURITYMODE_INVALID:
- response->responseHeader.serviceResult = UA_STATUSCODE_BADSECURITYMODEREJECTED;
- return response->responseHeader.serviceResult;
- // fall through and handle afterwards
- /* case UA_MESSAGESECURITYMODE_NONE: */
- /* UA_ByteString_copy(&request->clientNonce, &entry->channel.clientNonce); */
- /* break; */
- case UA_MESSAGESECURITYMODE_SIGN:
- case UA_MESSAGESECURITYMODE_SIGNANDENCRYPT:
- response->responseHeader.serviceResult = UA_STATUSCODE_BADSECURITYMODEREJECTED;
- return response->responseHeader.serviceResult;
- default:
- // do nothing
- break;
- }
- channel_list_entry *entry = UA_malloc(sizeof(channel_list_entry));
- if(!entry) return UA_STATUSCODE_BADOUTOFMEMORY;
- UA_SecureChannel_init(&entry->channel);
- response->responseHeader.stringTableSize = 0;
- response->responseHeader.timestamp = UA_DateTime_now();
- entry->channel.connection = conn;
- conn->channel = &entry->channel;
- 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;
- UA_ByteString_copy(&request->clientNonce, &entry->channel.clientNonce);
- entry->channel.serverAsymAlgSettings.securityPolicyUri =
- UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#None");
- 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);
- conn->channel = &entry->channel;
- return UA_STATUSCODE_GOOD;
- }
- UA_StatusCode 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_STATUSCODE_BADINTERNALERROR;
- channel->securityToken.tokenId = cm->lastTokenId++;
- channel->securityToken.createdAt = UA_DateTime_now(); // todo: is wanted?
- channel->securityToken.revisedLifetime = (request->requestedLifetime > cm->maxChannelLifetime) ?
- cm->maxChannelLifetime : request->requestedLifetime;
- if(channel->serverNonce.data != UA_NULL)
- UA_ByteString_deleteMembers(&channel->serverNonce);
- UA_SecureChannel_generateNonce(&channel->serverNonce);
- UA_ByteString_copy(&channel->serverNonce, &response->serverNonce);
- UA_ChannelSecurityToken_copy(&channel->securityToken, &response->securityToken);
- return UA_STATUSCODE_GOOD;
- }
- UA_SecureChannel * UA_SecureChannelManager_get(UA_SecureChannelManager *cm, UA_UInt32 channelId) {
- channel_list_entry *entry;
- LIST_FOREACH(entry, &cm->channels, pointers) {
- if(entry->channel.securityToken.channelId == channelId)
- return &entry->channel;
- }
- return UA_NULL;
- }
- UA_StatusCode UA_SecureChannelManager_close(UA_SecureChannelManager *cm, UA_UInt32 channelId) {
- // TODO lock access
- channel_list_entry *entry;
- LIST_FOREACH(entry, &cm->channels, pointers) {
- if(entry->channel.securityToken.channelId == channelId) {
- UA_Connection *c = entry->channel.connection;
- if(c) {
- UA_Connection_detachSecureChannel(c);
- c->close(c);
- }
- entry->channel.session = UA_NULL;
- UA_SecureChannel_deleteMembers(&entry->channel);
- LIST_REMOVE(entry, pointers);
- UA_free(entry);
- return UA_STATUSCODE_GOOD;
- }
- }
- return UA_STATUSCODE_BADINTERNALERROR;
- }
|