Coverage Report

Created: 2026-01-17 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open62541/src/server/ua_services_session.c
Line
Count
Source
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
 *
5
 *    Copyright 2014-2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
6
 *    Copyright 2014-2017 (c) Florian Palm
7
 *    Copyright 2014-2016 (c) Sten Grüner
8
 *    Copyright 2015 (c) Chris Iatrou
9
 *    Copyright 2015 (c) Oleksiy Vasylyev
10
 *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
11
 *    Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB
12
 *    Copyright 2019 (c) Kalycito Infotech Private Limited
13
 *    Copyright 2018-2020 (c) HMS Industrial Networks AB (Author: Jonas Green)
14
 *    Copyright 2025 (c) Siemens AG (Author: Tin Raic)
15
 */
16
17
#include "ua_server_internal.h"
18
#include "ua_services.h"
19
20
void
21
notifySession(UA_Server *server, UA_Session *session,
22
0
              UA_ApplicationNotificationType type) {
23
    /* Nothing to do */
24
0
    if(!server->config.globalNotificationCallback &&
25
0
       !server->config.sessionNotificationCallback)
26
0
        return;
27
28
    /* Set up the payload */
29
0
    size_t payloadSize = 6 + session->attributes.mapSize;
30
0
    UA_STACKARRAY(UA_KeyValuePair, payloadData, payloadSize);
31
0
    UA_KeyValueMap payloadMap = {payloadSize, payloadData};
32
0
    payloadData[0].key = UA_QUALIFIEDNAME(0, "session-id");
33
0
    UA_Variant_setScalar(&payloadData[0].value, &session->sessionId,
34
0
                         &UA_TYPES[UA_TYPES_NODEID]);
35
0
    payloadData[1].key = UA_QUALIFIEDNAME(0, "securechannel-id");
36
0
    UA_UInt32 secureChannelId = 0;
37
0
    if(session->channel)
38
0
        secureChannelId = session->channel->securityToken.channelId;
39
0
    UA_Variant_setScalar(&payloadData[1].value, &secureChannelId,
40
0
                         &UA_TYPES[UA_TYPES_UINT32]);
41
0
    payloadData[2].key = UA_QUALIFIEDNAME(0, "session-name");
42
0
    UA_Variant_setScalar(&payloadData[2].value, &session->sessionName,
43
0
                         &UA_TYPES[UA_TYPES_STRING]);
44
0
    payloadData[3].key = UA_QUALIFIEDNAME(0, "client-description");
45
0
    UA_Variant_setScalar(&payloadData[3].value, &session->clientDescription,
46
0
                         &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
47
0
    payloadData[4].key = UA_QUALIFIEDNAME(0, "client-user-id");
48
0
    UA_Variant_setScalar(&payloadData[4].value, &session->clientUserIdOfSession,
49
0
                         &UA_TYPES[UA_TYPES_STRING]);
50
0
    payloadData[5].key = UA_QUALIFIEDNAME(0, "locale-ids");
51
0
    UA_Variant_setArray(&payloadData[5].value, session->localeIds,
52
0
                        session->localeIdsSize, &UA_TYPES[UA_TYPES_STRING]);
53
54
0
    memcpy(&payloadData[6], session->attributes.map,
55
0
           sizeof(UA_KeyValuePair) * session->attributes.mapSize);
56
57
    /* Call the notification callback */
58
0
    if(server->config.sessionNotificationCallback)
59
0
        server->config.sessionNotificationCallback(server, type, payloadMap);
60
0
    if(server->config.globalNotificationCallback)
61
0
        server->config.globalNotificationCallback(server, type, payloadMap);
62
0
}
63
64
/* Delayed callback to free the session memory */
65
static void
66
0
removeSessionCallback(UA_Server *server, session_list_entry *entry) {
67
0
    lockServer(server);
68
0
    UA_Session_clear(&entry->session, server);
69
0
    unlockServer(server);
70
0
    UA_free(entry);
71
0
}
72
73
void
74
UA_Session_remove(UA_Server *server, UA_Session *session,
75
0
                  UA_ShutdownReason shutdownReason) {
76
0
    UA_LOCK_ASSERT(&server->serviceMutex);
77
78
    /* Remove the Subscriptions */
79
0
#ifdef UA_ENABLE_SUBSCRIPTIONS
80
0
    UA_Subscription *sub, *tempsub;
81
0
    TAILQ_FOREACH_SAFE(sub, &session->subscriptions, sessionListEntry, tempsub) {
82
0
        UA_Subscription_delete(server, sub);
83
0
    }
84
85
0
    UA_PublishResponseEntry *entry;
86
0
    while((entry = UA_Session_dequeuePublishReq(session))) {
87
0
        UA_PublishResponse_clear(&entry->response);
88
0
        UA_free(entry);
89
0
    }
90
0
#endif
91
92
    /* Callback into userland access control */
93
0
    if(server->config.accessControl.closeSession) {
94
0
        server->config.accessControl.
95
0
            closeSession(server, &server->config.accessControl,
96
0
                         &session->sessionId, session->context);
97
0
    }
98
99
    /* Detach the Session from the SecureChannel */
100
0
    UA_Session_detachFromSecureChannel(server, session);
101
102
    /* Deactivate the session */
103
0
    if(session->activated) {
104
0
        session->activated = false;
105
0
        server->activeSessionCount--;
106
0
    }
107
108
    /* Detach the session from the session manager and make the capacity
109
     * available */
110
0
    session_list_entry *sentry = container_of(session, session_list_entry, session);
111
0
    LIST_REMOVE(sentry, pointers);
112
0
    server->sessionCount--;
113
114
0
    switch(shutdownReason) {
115
0
    case UA_SHUTDOWNREASON_CLOSE:
116
0
    case UA_SHUTDOWNREASON_PURGE:
117
0
        break;
118
0
    case UA_SHUTDOWNREASON_TIMEOUT:
119
0
        server->serverDiagnosticsSummary.sessionTimeoutCount++;
120
0
        break;
121
0
    case UA_SHUTDOWNREASON_REJECT:
122
0
        server->serverDiagnosticsSummary.rejectedSessionCount++;
123
0
        break;
124
0
    case UA_SHUTDOWNREASON_SECURITYREJECT:
125
0
        server->serverDiagnosticsSummary.securityRejectedSessionCount++;
126
0
        break;
127
0
    case UA_SHUTDOWNREASON_ABORT:
128
0
        server->serverDiagnosticsSummary.sessionAbortCount++;
129
0
        break;
130
0
    default:
131
0
        UA_assert(false);
132
0
        break;
133
0
    }
134
135
    /* Notify the application */
136
0
    notifySession(server, session, UA_APPLICATIONNOTIFICATIONTYPE_SESSION_CLOSED);
137
138
    /* Add a delayed callback to remove the session when the currently
139
     * scheduled jobs have completed */
140
0
    sentry->cleanupCallback.callback = (UA_Callback)removeSessionCallback;
141
0
    sentry->cleanupCallback.application = server;
142
0
    sentry->cleanupCallback.context = sentry;
143
0
    UA_EventLoop *el = server->config.eventLoop;
144
0
    el->addDelayedCallback(el, &sentry->cleanupCallback);
145
0
}
146
147
void
148
0
cleanupSessions(UA_Server *server, UA_DateTime nowMonotonic) {
149
0
    UA_LOCK_ASSERT(&server->serviceMutex);
150
0
    session_list_entry *sentry, *temp;
151
0
    LIST_FOREACH_SAFE(sentry, &server->sessions, pointers, temp) {
152
        /* Session has timed out? */
153
0
        if(sentry->session.validTill >= nowMonotonic)
154
0
            continue;
155
0
        UA_LOG_INFO_SESSION(server->config.logging, &sentry->session,
156
0
                            "Session has timed out");
157
0
        UA_Session_remove(server, &sentry->session, UA_SHUTDOWNREASON_TIMEOUT);
158
0
    }
159
0
}
160
161
/************/
162
/* Services */
163
/************/
164
165
UA_Session *
166
0
getSessionByToken(UA_Server *server, const UA_NodeId *token) {
167
0
    UA_LOCK_ASSERT(&server->serviceMutex);
168
169
0
    session_list_entry *current = NULL;
170
0
    LIST_FOREACH(current, &server->sessions, pointers) {
171
        /* Token does not match */
172
0
        if(!UA_NodeId_equal(&current->session.authenticationToken, token))
173
0
            continue;
174
175
        /* Session has timed out */
176
0
        UA_EventLoop *el = server->config.eventLoop;
177
0
        UA_DateTime now = el->dateTime_nowMonotonic(el);
178
0
        if(now > current->session.validTill) {
179
0
            UA_LOG_INFO_SESSION(server->config.logging, &current->session,
180
0
                                "Client tries to use a session that has timed out");
181
0
            return NULL;
182
0
        }
183
184
0
        return &current->session;
185
0
    }
186
187
0
    return NULL;
188
0
}
189
190
UA_Session *
191
0
getSessionById(UA_Server *server, const UA_NodeId *sessionId) {
192
0
    UA_LOCK_ASSERT(&server->serviceMutex);
193
194
0
    session_list_entry *current = NULL;
195
0
    LIST_FOREACH(current, &server->sessions, pointers) {
196
        /* Token does not match */
197
0
        if(!UA_NodeId_equal(&current->session.sessionId, sessionId))
198
0
            continue;
199
200
        /* Session has timed out */
201
0
        UA_EventLoop *el = server->config.eventLoop;
202
0
        UA_DateTime now = el->dateTime_nowMonotonic(el);
203
0
        if(now > current->session.validTill) {
204
0
            UA_LOG_INFO_SESSION(server->config.logging, &current->session,
205
0
                                "Client tries to use a session that has timed out");
206
0
            return NULL;
207
0
        }
208
209
0
        return &current->session;
210
0
    }
211
212
0
    if(UA_NodeId_equal(sessionId, &server->adminSession.sessionId))
213
0
        return &server->adminSession;
214
215
0
    return NULL;
216
0
}
217
218
static UA_StatusCode
219
signCreateSessionResponse(UA_Server *server, UA_SecureChannel *channel,
220
                          const UA_CreateSessionRequest *request,
221
0
                          UA_CreateSessionResponse *response) {
222
0
    if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
223
0
       channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
224
0
        return UA_STATUSCODE_GOOD;
225
226
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
227
0
    void *cc = channel->channelContext;
228
0
    UA_SignatureData *signatureData = &response->serverSignature;
229
230
    /* Prepare the signature */
231
0
    const UA_SecurityPolicySignatureAlgorithm *signAlg = &sp->asymSignatureAlgorithm;
232
0
    size_t signatureSize = signAlg->getLocalSignatureSize(sp, cc);
233
0
    UA_StatusCode retval = UA_String_copy(&signAlg->uri, &signatureData->algorithm);
234
0
    retval |= UA_ByteString_allocBuffer(&signatureData->signature, signatureSize);
235
0
    if(retval != UA_STATUSCODE_GOOD)
236
0
        return retval;
237
238
    /* Allocate a temp buffer */
239
0
    size_t dataToSignSize =
240
0
        request->clientCertificate.length + request->clientNonce.length;
241
0
    UA_ByteString dataToSign;
242
0
    retval = UA_ByteString_allocBuffer(&dataToSign, dataToSignSize);
243
0
    if(retval != UA_STATUSCODE_GOOD)
244
0
        return retval; /* signatureData->signature is cleaned up with the response */
245
246
    /* Sign the signature */
247
0
    memcpy(dataToSign.data, request->clientCertificate.data,
248
0
           request->clientCertificate.length);
249
0
    memcpy(dataToSign.data + request->clientCertificate.length,
250
0
           request->clientNonce.data, request->clientNonce.length);
251
0
    retval = signAlg->sign(sp, cc, &dataToSign, &signatureData->signature);
252
253
    /* Clean up */
254
0
    UA_ByteString_clear(&dataToSign);
255
0
    return retval;
256
0
}
257
258
static UA_StatusCode
259
addEphemeralKeyAdditionalHeader(UA_Server *server, const UA_SecurityPolicy *sp,
260
0
                                void *channelContext, UA_ExtensionObject *ah) {
261
    /* Allocate additional parameters */
262
0
    UA_AdditionalParametersType *ap = UA_AdditionalParametersType_new();
263
0
    if(!ap)
264
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
265
266
    /* Set the additional parameters in the additional header. They also get
267
     * cleaned up from there in the error case. */
268
0
    UA_ExtensionObject_setValue(ah, ap, &UA_TYPES[UA_TYPES_ADDITIONALPARAMETERSTYPE]);
269
270
    /* UA_KeyValueMap has the identical layout. And better helper methods. */
271
0
    UA_KeyValueMap *map = (UA_KeyValueMap*)ap;
272
273
    /* Add the PolicyUri to the map */
274
0
    UA_StatusCode res =
275
0
        UA_KeyValueMap_setScalar(map, UA_QUALIFIEDNAME(0, "ECDHPolicyUri"),
276
0
                                 &sp->policyUri, &UA_TYPES[UA_TYPES_STRING]);
277
0
    if(res != UA_STATUSCODE_GOOD)
278
0
        return res;
279
280
    /* Allocate the EphemeralKey structure */
281
0
    UA_EphemeralKeyType *ephKey = UA_EphemeralKeyType_new();
282
0
    if(!ephKey)
283
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
284
285
    /* Add the EphemeralKeyto the map */
286
0
    res = UA_KeyValueMap_setScalarShallow(map, UA_QUALIFIEDNAME(0, "ECDHKey"),
287
0
                                          ephKey, &UA_TYPES[UA_TYPES_EPHEMERALKEYTYPE]);
288
0
    if(res != UA_STATUSCODE_GOOD)
289
0
        return res;
290
291
    /* Allocate the ephemeral key buffer to the exact size of the ephemeral key
292
     * for the used ECC policy so that the nonce generation function knows that
293
     * it needs to generate an ephemeral key and not some other random byte
294
     * string.
295
     *
296
     * TODO: There should be a more stable way to signal the generation of an
297
     * ephemeral key */
298
0
    res = UA_ByteString_allocBuffer(&ephKey->publicKey, sp->nonceLength);
299
0
    if(res != UA_STATUSCODE_GOOD)
300
0
        return res;
301
302
    /* Generate the ephemeral key
303
     * TODO: Don't we have to persist the key locally? */
304
0
    res = sp->generateNonce(sp, channelContext, &ephKey->publicKey);
305
0
    if(res != UA_STATUSCODE_GOOD)
306
0
        return res;
307
308
    /* Create the signature
309
     * TODO: Check whether the symmetric or asymmetric signing algorithm is
310
     * needed here */
311
0
    size_t signatureSize = sp->symSignatureAlgorithm.
312
0
        getLocalSignatureSize(sp, channelContext);
313
0
    res = UA_ByteString_allocBuffer(&ephKey->signature, signatureSize);
314
0
    if(res != UA_STATUSCODE_GOOD)
315
0
        return res;
316
0
    return sp->symSignatureAlgorithm.
317
0
        sign(sp, channelContext, &ephKey->publicKey, &ephKey->signature);
318
0
}
319
320
/* Creates and adds a session. But it is not yet attached to a secure channel. */
321
UA_StatusCode
322
UA_Session_create(UA_Server *server, UA_SecureChannel *channel,
323
0
                  const UA_CreateSessionRequest *request, UA_Session **session) {
324
0
    UA_LOCK_ASSERT(&server->serviceMutex);
325
326
0
    if(server->sessionCount >= server->config.maxSessions) {
327
0
        UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
328
0
                               "Could not create a Session - Server limits reached");
329
0
        return UA_STATUSCODE_BADTOOMANYSESSIONS;
330
0
    }
331
332
0
    session_list_entry *newentry = (session_list_entry*)
333
0
        UA_malloc(sizeof(session_list_entry));
334
0
    if(!newentry)
335
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
336
337
    /* Initialize the Session */
338
0
    UA_Session_init(&newentry->session);
339
0
    newentry->session.sessionId = UA_NODEID_GUID(1, UA_Guid_random());
340
0
    newentry->session.authenticationToken = UA_NODEID_GUID(1, UA_Guid_random());
341
342
0
    newentry->session.timeout = server->config.maxSessionTimeout;
343
0
    if(request->requestedSessionTimeout <= server->config.maxSessionTimeout &&
344
0
       request->requestedSessionTimeout > 0)
345
0
        newentry->session.timeout = request->requestedSessionTimeout;
346
347
    /* Attach the session to the channel. But don't activate for now. */
348
0
    if(channel)
349
0
        UA_Session_attachToSecureChannel(server, &newentry->session, channel);
350
351
0
    UA_EventLoop *el = server->config.eventLoop;
352
0
    UA_DateTime now = el->dateTime_now(el);
353
0
    UA_DateTime nowMonotonic = el->dateTime_nowMonotonic(el);
354
0
    UA_Session_updateLifetime(&newentry->session, now, nowMonotonic);
355
356
    /* Add to the server */
357
0
    LIST_INSERT_HEAD(&server->sessions, newentry, pointers);
358
0
    server->sessionCount++;
359
360
    /* Notify the application */
361
0
    notifySession(server, &newentry->session,
362
0
                  UA_APPLICATIONNOTIFICATIONTYPE_SESSION_CREATED);
363
364
    /* Return */
365
0
    *session = &newentry->session;
366
0
    return UA_STATUSCODE_GOOD;
367
0
}
368
369
void
370
Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
371
                      const UA_CreateSessionRequest *request,
372
0
                      UA_CreateSessionResponse *response) {
373
0
    UA_LOCK_ASSERT(&server->serviceMutex);
374
0
    UA_LOG_DEBUG_CHANNEL(server->config.logging, channel, "Trying to create session");
375
376
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
377
0
    void *cc = channel->channelContext;
378
379
0
    if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
380
0
       channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
381
        /* Compare the clientCertificate with the remoteCertificate of the
382
         * channel. Both the clientCertificate of this request and the
383
         * remoteCertificate of the channel may contain a partial or a complete
384
         * certificate chain. The compareCertificate function will compare the
385
         * first certificate of each chain. The end certificate shall be located
386
         * first in the chain according to the OPC UA specification Part 6
387
         * (1.04), chapter 6.2.3.*/
388
0
        UA_StatusCode res = sp->compareCertificate(sp, cc, &request->clientCertificate);
389
0
        if(res != UA_STATUSCODE_GOOD) {
390
0
            UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
391
0
                                 "The client certificate did not validate");
392
0
            response->responseHeader.serviceResult = UA_STATUSCODE_BADCERTIFICATEINVALID;
393
0
            server->serverDiagnosticsSummary.securityRejectedSessionCount++;
394
0
            server->serverDiagnosticsSummary.rejectedSessionCount++;
395
0
            return;
396
0
        }
397
0
    }
398
399
0
    UA_assert(channel->securityToken.channelId != 0);
400
401
    /* Check the nonce */
402
0
    if(channel->securityPolicy->policyType != UA_SECURITYPOLICYTYPE_NONE &&
403
0
       request->clientNonce.length < 32) {
404
0
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
405
0
                             "The nonce provided by the client has the wrong length");
406
0
        server->serverDiagnosticsSummary.securityRejectedSessionCount++;
407
0
        server->serverDiagnosticsSummary.rejectedSessionCount++;
408
0
        response->responseHeader.serviceResult = UA_STATUSCODE_BADNONCEINVALID;
409
0
        return;
410
0
    }
411
412
    /* Check the client certificate (against the ApplicationDescription,
413
     * cryptographic checking is done separately in the SecureChannel) */
414
0
    if(request->clientCertificate.length > 0) {
415
0
        UA_StatusCode res =
416
0
            UA_CertificateUtils_verifyApplicationUri(&request->clientCertificate,
417
0
                                &request->clientDescription.applicationUri);
418
0
        if(res != UA_STATUSCODE_GOOD) {
419
0
            if(server->config.allowAllCertificateUris <= UA_RULEHANDLING_WARN) {
420
0
                UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
421
0
                                     "The client certificate's ApplicationUri "
422
0
                                     "could not be verified against the ApplicationUri "
423
0
                                     "%S from the client's ApplicationDescription (%s)",
424
0
                                     request->clientDescription.applicationUri,
425
0
                                     UA_StatusCode_name(res));
426
0
            }
427
0
            if(server->config.allowAllCertificateUris <= UA_RULEHANDLING_ABORT) {
428
0
                response->responseHeader.serviceResult = res;
429
0
                server->serverDiagnosticsSummary.securityRejectedSessionCount++;
430
0
                server->serverDiagnosticsSummary.rejectedSessionCount++;
431
0
                return;
432
0
            }
433
0
        }
434
0
    }
435
436
    /* Create the Session */
437
0
    UA_Session *newSession = NULL;
438
0
    response->responseHeader.serviceResult =
439
0
        UA_Session_create(server, channel, request, &newSession);
440
0
    if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
441
0
        UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
442
0
                               "Processing CreateSessionRequest failed");
443
0
        server->serverDiagnosticsSummary.rejectedSessionCount++;
444
0
        return;
445
0
    }
446
447
    /* If the session name is empty, use the generated SessionId */
448
0
    response->responseHeader.serviceResult |=
449
0
        UA_String_copy(&request->sessionName, &newSession->sessionName);
450
0
    if(newSession->sessionName.length == 0)
451
0
        response->responseHeader.serviceResult |=
452
0
            UA_NodeId_print(&newSession->sessionId, &newSession->sessionName);
453
454
0
    response->responseHeader.serviceResult |= UA_Session_generateNonce(newSession);
455
0
    newSession->maxResponseMessageSize = request->maxResponseMessageSize;
456
0
    newSession->maxRequestMessageSize = channel->config.localMaxMessageSize;
457
0
    response->responseHeader.serviceResult |=
458
0
        UA_ApplicationDescription_copy(&request->clientDescription,
459
0
                                       &newSession->clientDescription);
460
461
0
#ifdef UA_ENABLE_DIAGNOSTICS
462
0
    response->responseHeader.serviceResult |=
463
0
        UA_String_copy(&request->serverUri, &newSession->diagnostics.serverUri);
464
0
    response->responseHeader.serviceResult |=
465
0
        UA_String_copy(&request->endpointUrl, &newSession->diagnostics.endpointUrl);
466
0
#endif
467
468
0
    if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
469
0
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
470
0
                             "Could not create the new session (%s)",
471
0
                             UA_StatusCode_name(response->responseHeader.serviceResult));
472
0
        UA_Session_remove(server, newSession, UA_SHUTDOWNREASON_REJECT);
473
0
        return;
474
0
    }
475
476
    /* Prepare the response */
477
0
    response->sessionId = newSession->sessionId;
478
0
    response->revisedSessionTimeout = (UA_Double)newSession->timeout;
479
0
    response->authenticationToken = newSession->authenticationToken;
480
0
    response->responseHeader.serviceResult |=
481
0
        UA_ByteString_copy(&newSession->serverNonce, &response->serverNonce);
482
483
    /* Copy the server's endpointdescriptions into the response */
484
0
    response->responseHeader.serviceResult |=
485
0
        setCurrentEndPointsArray(server, request->endpointUrl, NULL, 0,
486
0
                                 &response->serverEndpoints,
487
0
                                 &response->serverEndpointsSize);
488
489
    /* Return the server certificate from the SecurityPolicy of the current
490
     * channel. Or, if the channel is unencrypted, return the standard policy
491
     * used for usertoken encryption. */
492
0
    if(sp->policyType == UA_SECURITYPOLICYTYPE_NONE ||
493
0
       sp->localCertificate.length == 0)
494
0
        sp = getDefaultEncryptedSecurityPolicy(server);
495
0
    if(sp)
496
0
        response->responseHeader.serviceResult |=
497
0
            UA_ByteString_copy(&sp->localCertificate, &response->serverCertificate);
498
499
0
    if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
500
0
        UA_Session_remove(server, newSession, UA_SHUTDOWNREASON_REJECT);
501
0
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
502
0
                             "Could not prepare the CreateSessionResponse (%s)",
503
0
                             UA_StatusCode_name(response->responseHeader.serviceResult));
504
0
        return;
505
0
    }
506
507
    /* If ECC policy, create an ephemeral key to be returned in the response */
508
0
    if(sp && sp->policyType == UA_SECURITYPOLICYTYPE_ECC) {
509
0
        response->responseHeader.serviceResult =
510
0
            addEphemeralKeyAdditionalHeader(server, sp, channel->channelContext,
511
0
                                            &response->responseHeader.additionalHeader);
512
0
        if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
513
0
            UA_Session_remove(server, newSession, UA_SHUTDOWNREASON_REJECT);
514
0
            UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
515
0
                                 "Could not prepare the ephemeral key (%s)",
516
0
                                 UA_StatusCode_name(response->responseHeader.serviceResult));
517
0
            return;
518
0
        }
519
0
        UA_LOG_DEBUG(server->config.logging, UA_LOGCATEGORY_SESSION,
520
0
                    "[CreateSession] Ephemeral Key created");
521
0
    }
522
523
    /* Sign the signature */
524
0
    response->responseHeader.serviceResult |=
525
0
       signCreateSessionResponse(server, channel, request, response);
526
0
    if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
527
0
        UA_Session_remove(server, newSession, UA_SHUTDOWNREASON_REJECT);
528
0
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
529
0
                             "Could not sign the CreateSessionResponse (%s)",
530
0
                             UA_StatusCode_name(response->responseHeader.serviceResult));
531
0
        return;
532
0
    }
533
534
0
#ifdef UA_ENABLE_DIAGNOSTICS
535
0
    UA_EventLoop *el = server->config.eventLoop;
536
0
    newSession->diagnostics.clientConnectionTime = el->dateTime_now(el);
537
0
    newSession->diagnostics.clientLastContactTime =
538
0
        newSession->diagnostics.clientConnectionTime;
539
540
    /* Create the object in the information model */
541
0
    createSessionObject(server, newSession);
542
0
#endif
543
544
0
    UA_LOG_INFO_SESSION(server->config.logging, newSession, "Session created");
545
0
}
546
547
static UA_StatusCode
548
checkCertificateSignature(const UA_Server *server, const UA_SecurityPolicy *sp,
549
                          void *channelContext, const UA_ByteString *serverNonce,
550
                          const UA_SignatureData *signature,
551
0
                          const bool isUserTokenSignature) {
552
    /* Check for zero signature length */
553
0
    if(signature->signature.length == 0) {
554
0
        if(isUserTokenSignature)
555
0
            return UA_STATUSCODE_BADUSERSIGNATUREINVALID;
556
0
        return UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID;
557
0
    }
558
559
0
    if(!sp)
560
0
        return UA_STATUSCODE_BADINTERNALERROR;
561
562
    /* Data to verify is calculated by appending the serverNonce to the local
563
     * certificate */
564
0
    const UA_ByteString *localCertificate = &sp->localCertificate;
565
0
    UA_ByteString dataToVerify;
566
0
    size_t dataToVerifySize = localCertificate->length + serverNonce->length;
567
0
    UA_StatusCode retval = UA_ByteString_allocBuffer(&dataToVerify, dataToVerifySize);
568
0
    if(retval != UA_STATUSCODE_GOOD)
569
0
        return retval;
570
571
0
    memcpy(dataToVerify.data, localCertificate->data, localCertificate->length);
572
0
    memcpy(dataToVerify.data + localCertificate->length,
573
0
           serverNonce->data, serverNonce->length);
574
0
    retval = sp->asymSignatureAlgorithm.
575
0
        verify(sp, channelContext, &dataToVerify, &signature->signature);
576
0
    UA_ByteString_clear(&dataToVerify);
577
0
    if(retval != UA_STATUSCODE_GOOD) {
578
0
        if(isUserTokenSignature)
579
0
            retval = UA_STATUSCODE_BADUSERSIGNATUREINVALID;
580
0
        else
581
0
            retval = UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID;
582
0
    }
583
0
    return retval;
584
0
}
585
586
/* Always sets tokenSp (default: SecurityPolicy of the channel) */
587
static const UA_UserTokenPolicy *
588
selectTokenPolicy(UA_Server *server, UA_SecureChannel *channel,
589
                  UA_Session *session, const UA_ExtensionObject *identityToken,
590
                  const UA_EndpointDescription *ed,
591
0
                  const UA_SecurityPolicy **tokenSp) {
592
    /* If no UserTokenPolicies are configured in the endpoint, then use
593
     * those configured in the AccessControl plugin. */
594
0
    size_t identPoliciesSize = ed->userIdentityTokensSize;
595
0
    const UA_UserTokenPolicy *identPolicies = ed->userIdentityTokens;
596
0
    if(identPoliciesSize == 0) {
597
0
        identPoliciesSize = server->config.accessControl.userTokenPoliciesSize;
598
0
        identPolicies = server->config.accessControl.userTokenPolicies;
599
0
    }
600
601
    /* Match the UserTokenType */
602
0
    const UA_DataType *tokenDataType = identityToken->content.decoded.type;
603
0
    for(size_t j = 0; j < identPoliciesSize; j++) {
604
0
        const UA_UserTokenPolicy *pol = &identPolicies[j];
605
606
        /* Part 4, Section 5.6.3.2, Table 17: A NULL or empty
607
         * UserIdentityToken should be treated as Anonymous */
608
0
        if(identityToken->encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY &&
609
0
           pol->tokenType == UA_USERTOKENTYPE_ANONYMOUS) {
610
0
            *tokenSp = channel->securityPolicy;
611
0
            return pol;
612
0
        }
613
614
        /* Expect decoded content if not anonymous */
615
0
        if(!tokenDataType)
616
0
            continue;
617
618
        /* Match the DataType of the provided token with the policy */
619
0
        switch(pol->tokenType) {
620
0
        case UA_USERTOKENTYPE_ANONYMOUS:
621
0
            if(tokenDataType != &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN])
622
0
                continue;
623
0
            break;
624
0
        case UA_USERTOKENTYPE_USERNAME:
625
0
            if(tokenDataType != &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN])
626
0
                continue;
627
0
            break;
628
0
        case UA_USERTOKENTYPE_CERTIFICATE:
629
0
            if(tokenDataType != &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN])
630
0
                continue;
631
0
            break;
632
0
        case UA_USERTOKENTYPE_ISSUEDTOKEN:
633
0
            if(tokenDataType != &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN])
634
0
                continue;
635
0
            break;
636
0
        default:
637
0
            continue;
638
0
        }
639
640
        /* All valid token data types start with a string policyId. Casting
641
         * to anonymous hence works for all of them. */
642
0
        UA_AnonymousIdentityToken *token = (UA_AnonymousIdentityToken*)
643
0
            identityToken->content.decoded.data;
644
645
        /* In setCurrentEndPointsArray we prepend the PolicyId with the
646
         * SecurityMode of the endpoint and the postfix of the
647
         * SecurityPolicyUri to make it unique. Check the PolicyId. */
648
0
        if(pol->policyId.length > token->policyId.length)
649
0
            continue;
650
0
        UA_String policyPrefix = token->policyId;
651
0
        policyPrefix.length = pol->policyId.length;
652
0
        if(!UA_String_equal(&policyPrefix, &pol->policyId))
653
0
            continue;
654
655
        /* Get the SecurityPolicy for the endpoint from the postfix */
656
0
        UA_String utPolPostfix = securityPolicyUriPostfix(token->policyId);
657
0
        UA_SecurityPolicy *candidateSp =
658
0
            getSecurityPolicyByPostfix(server, utPolPostfix);
659
0
        if(!candidateSp) {
660
0
            UA_LOG_WARNING_SESSION(server->config.logging, session,
661
0
                                   "ActivateSession: The UserTokenPolicy of "
662
0
                                   "the endpoint defines an unknown "
663
0
                                   "SecurityPolicy %S",
664
0
                                   pol->securityPolicyUri);
665
0
            continue;
666
0
        }
667
668
        /* A non-anonymous authentication token is transmitted over an
669
         * unencrypted SecureChannel */
670
0
        if(pol->tokenType != UA_USERTOKENTYPE_ANONYMOUS &&
671
0
           channel->securityPolicy->policyType == UA_SECURITYPOLICYTYPE_NONE &&
672
0
           candidateSp->policyType == UA_SECURITYPOLICYTYPE_NONE) {
673
            /* Check if the allowNonePolicyPassword option is set.
674
             * But this exception only works for Username/Password. */
675
0
            if(!server->config.allowNonePolicyPassword ||
676
0
               pol->tokenType != UA_USERTOKENTYPE_USERNAME)
677
0
                continue;
678
0
        }
679
680
        /* Found a match policy */
681
0
        *tokenSp = candidateSp;
682
0
        return pol;
683
0
    }
684
685
0
    return NULL;
686
0
}
687
688
static void
689
selectEndpointAndTokenPolicy(UA_Server *server, UA_SecureChannel *channel,
690
                             UA_Session *session,
691
                             const UA_ExtensionObject *identityToken,
692
                             const UA_EndpointDescription **ed,
693
                             const UA_UserTokenPolicy **utp,
694
0
                             const UA_SecurityPolicy **tokenSp) {
695
0
    UA_ServerConfig *sc = &server->config;
696
0
    for(size_t i = 0; i < sc->endpointsSize; ++i) {
697
0
        const UA_EndpointDescription *desc = &sc->endpoints[i];
698
699
        /* Match the Security Mode */
700
0
        if(desc->securityMode != channel->securityMode)
701
0
            continue;
702
703
        /* Match the SecurityPolicy of the endpoint with the current channel */
704
0
        if(!UA_String_equal(&desc->securityPolicyUri,
705
0
                            &channel->securityPolicy->policyUri))
706
0
            continue;
707
708
        /* Select the UserTokenPolicy from the Endpoint */
709
0
        *utp = selectTokenPolicy(server, channel, session,
710
0
                                 identityToken, desc, tokenSp);
711
0
        if(*utp) {
712
            /* Match found */
713
0
            *ed = desc;
714
0
            return;
715
0
        }
716
0
    }
717
0
}
718
719
static UA_StatusCode
720
decryptUserToken(UA_Server *server, UA_Session *session,
721
                 UA_SecureChannel *channel, const UA_SecurityPolicy *sp,
722
0
                 const UA_String encryptionAlgorithm, UA_ByteString *encrypted) {
723
    /* If SecurityPolicy is None there shall be no EncryptionAlgorithm  */
724
0
    if(sp->policyType == UA_SECURITYPOLICYTYPE_NONE) {
725
0
        if(encryptionAlgorithm.length > 0)
726
0
            return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
727
0
        if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE) {
728
0
            UA_LOG_WARNING_SESSION(server->config.logging, session, "ActivateSession: "
729
0
                                   "Received an unencrypted UserToken. "
730
0
                                   "Is the server misconfigured to allow that?");
731
0
        }
732
0
        return UA_STATUSCODE_GOOD;
733
0
    }
734
735
    /* Test if the correct encryption algorithm is used */
736
0
    if(!UA_String_equal(&encryptionAlgorithm, &sp->asymEncryptionAlgorithm.uri))
737
0
        return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
738
739
    /* Encrypted password -- Create a temporary channel context.
740
     * TODO: We should not need a ChannelContext at all for asymmetric
741
     * decryption where the remote certificate is not used. */
742
0
    void *tempChannelContext = NULL;
743
0
    UA_StatusCode res = sp->newChannelContext(sp, &sp->localCertificate,
744
0
                                              &tempChannelContext);
745
0
    if(res != UA_STATUSCODE_GOOD) {
746
0
        UA_LOG_WARNING_SESSION(server->config.logging, session,
747
0
                               "ActivateSession: Failed to create a context for "
748
0
                               "the SecurityPolicy %S", sp->policyUri);
749
0
        return res;
750
0
    }
751
752
0
    UA_UInt32 secretLen = 0;
753
0
    UA_ByteString secret, tokenNonce;
754
0
    size_t tokenpos = 0;
755
0
    size_t offset = 0;
756
0
    UA_ByteString *sn = &session->serverNonce;
757
0
    const UA_SecurityPolicyEncryptionAlgorithm *asymEnc = &sp->asymEncryptionAlgorithm;
758
759
0
    res = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
760
761
    /* Decrypt the secret */
762
0
    if(UA_ByteString_copy(encrypted, &secret) != UA_STATUSCODE_GOOD ||
763
0
       asymEnc->decrypt(sp, tempChannelContext, &secret) != UA_STATUSCODE_GOOD)
764
0
        goto cleanup;
765
766
    /* The secret starts with a UInt32 length for the content */
767
0
    if(UA_UInt32_decodeBinary(&secret, &offset, &secretLen) != UA_STATUSCODE_GOOD)
768
0
        goto cleanup;
769
770
    /* The decrypted data must be large enough to include the Encrypted Token
771
     * Secret Format and the length field must indicate enough data to include
772
     * the server nonce. */
773
0
    if(secret.length < sizeof(UA_UInt32) + sn->length ||
774
0
       secret.length < sizeof(UA_UInt32) + secretLen ||
775
0
       secretLen < sn->length)
776
0
        goto cleanup;
777
778
    /* If the Encrypted Token Secret contains padding, the padding must be
779
     * zeroes according to the 1.04.1 specification errata, chapter 3. */
780
0
    for(size_t i = sizeof(UA_UInt32) + secretLen; i < secret.length; i++) {
781
0
        if(secret.data[i] != 0)
782
0
            goto cleanup;
783
0
    }
784
785
    /* The server nonce must match according to the 1.04.1 specification errata,
786
     * chapter 3. */
787
0
    tokenpos = sizeof(UA_UInt32) + secretLen - sn->length;
788
0
    tokenNonce.length = sn->length;
789
0
    tokenNonce.data = &secret.data[tokenpos];
790
0
    if(!UA_ByteString_equal(sn, &tokenNonce))
791
0
        goto cleanup;
792
793
    /* The password was decrypted successfully. Replace usertoken with the
794
     * decrypted password. The encryptionAlgorithm and policyId fields are left
795
     * in the UserToken as an indication for the AccessControl plugin that
796
     * evaluates the decrypted content. */
797
0
    memcpy(encrypted->data,
798
0
           &secret.data[sizeof(UA_UInt32)], secretLen - sn->length);
799
0
    encrypted->length = secretLen - sn->length;
800
0
    res = UA_STATUSCODE_GOOD;
801
802
0
 cleanup:
803
0
    UA_ByteString_clear(&secret);
804
805
    /* Remove the temporary channel context */
806
0
    sp->deleteChannelContext(sp, tempChannelContext);
807
808
0
    if(res != UA_STATUSCODE_GOOD) {
809
0
        UA_LOG_WARNING_SESSION(server->config.logging, session,
810
0
                               "ActivateSession: Failed to decrypt the "
811
0
                               "password with the StatusCode %s",
812
0
                               UA_StatusCode_name(res));
813
0
    }
814
0
    return res;
815
0
}
816
817
static UA_StatusCode
818
checkActivateSessionX509(UA_Server *server, UA_Session *session,
819
                         const UA_SecurityPolicy *sp, UA_X509IdentityToken* token,
820
0
                         const UA_SignatureData *tokenSignature) {
821
    /* The SecurityPolicy must not be None for the signature */
822
0
    if(sp->policyType == UA_SECURITYPOLICYTYPE_NONE)
823
0
        return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
824
825
    /* We need a channel context with the user certificate in order to reuse
826
     * the signature checking code. */
827
0
    void *tempChannelContext;
828
0
    UA_StatusCode res = sp->newChannelContext(sp, &token->certificateData,
829
0
                                              &tempChannelContext);
830
0
    if(res != UA_STATUSCODE_GOOD) {
831
0
        UA_LOG_WARNING_SESSION(server->config.logging, session,
832
0
                               "ActivateSession: Failed to create a context "
833
0
                               "for the SecurityPolicy %S", sp->policyUri);
834
0
        return res;
835
0
    }
836
837
    /* Check the user token signature */
838
0
    res = checkCertificateSignature(server, sp, tempChannelContext,
839
0
                                    &session->serverNonce, tokenSignature, true);
840
0
    if(res != UA_STATUSCODE_GOOD) {
841
0
        UA_LOG_WARNING_SESSION(server->config.logging, session,
842
0
                               "ActivateSession: User token signature check "
843
0
                               "failed with StatusCode %s", UA_StatusCode_name(res));
844
0
    }
845
846
    /* Delete the temporary channel context */
847
0
    sp->deleteChannelContext(sp, tempChannelContext);
848
0
    return res;
849
0
}
850
851
/* TODO: Check all of the following: The Server shall verify that the
852
 * Certificate the Client used to create the new SecureChannel is the same as
853
 * the Certificate used to create the original SecureChannel. In addition, the
854
 * Server shall verify that the Client supplied a UserIdentityToken that is
855
 * identical to the token currently associated with the Session. Once the Server
856
 * accepts the new SecureChannel it shall reject requests sent via the old
857
 * SecureChannel. */
858
859
#define UA_SESSION_REJECT                                               \
860
0
    do {                                                                \
861
0
        server->serverDiagnosticsSummary.rejectedSessionCount++;        \
862
0
        return;                                                         \
863
0
    } while(0)
864
865
#define UA_SECURITY_REJECT                                              \
866
0
    do {                                                                \
867
0
        server->serverDiagnosticsSummary.securityRejectedSessionCount++; \
868
0
        server->serverDiagnosticsSummary.rejectedSessionCount++;        \
869
0
        return;                                                         \
870
0
    } while(0)
871
872
void
873
Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
874
                        const UA_ActivateSessionRequest *req,
875
0
                        UA_ActivateSessionResponse *resp) {
876
0
    UA_LOCK_ASSERT(&server->serviceMutex);
877
878
    /* Get the session */
879
0
    UA_Session *session =
880
0
        getSessionByToken(server, &req->requestHeader.authenticationToken);
881
0
    if(!session) {
882
0
        UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
883
0
                               "ActivateSession: Session not found");
884
0
        resp->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
885
0
        UA_SESSION_REJECT;
886
0
    }
887
888
    /* Part 4, §5.6.3: When the ActivateSession Service is called for the
889
     * first time then the Server shall reject the request if the
890
     * SecureChannel is not same as the one associated with the
891
     * CreateSession request. Subsequent calls to ActivateSession may be
892
     * associated with different SecureChannels. */
893
0
    if(!session->activated && session->channel != channel) {
894
0
        UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
895
0
                               "ActivateSession: The Session has to be initially "
896
0
                               "activated on the SecureChannel that created it");
897
0
        resp->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
898
0
        UA_SESSION_REJECT;
899
0
    }
900
901
    /* Has the session timed out? */
902
0
    UA_EventLoop *el = server->config.eventLoop;
903
0
    UA_DateTime nowMonotonic = el->dateTime_nowMonotonic(el);
904
0
    if(session->validTill < nowMonotonic) {
905
0
        UA_LOG_WARNING_SESSION(server->config.logging, session,
906
0
                               "ActivateSession: The Session has timed out");
907
0
        resp->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
908
0
        UA_SESSION_REJECT;
909
0
    }
910
911
    /* Check the client signature */
912
0
    if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
913
0
       channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
914
0
        resp->responseHeader.serviceResult =
915
0
            checkCertificateSignature(server, channel->securityPolicy,
916
0
                                      channel->channelContext,
917
0
                                      &session->serverNonce,
918
0
                                      &req->clientSignature, false);
919
0
        if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
920
0
            UA_LOG_WARNING_SESSION(server->config.logging, session,
921
0
                                   "ActivateSession: Client signature check failed "
922
0
                                   "with StatusCode %s",
923
0
                                   UA_StatusCode_name(resp->responseHeader.serviceResult));
924
0
            UA_SECURITY_REJECT;
925
0
        }
926
0
    }
927
928
    /* Find the matching Endpoint with UserTokenPolicy.
929
     * Also sets the SecurityPolicy used to encrypt the token. */
930
0
    const UA_EndpointDescription *ed = NULL;
931
0
    const UA_UserTokenPolicy *utp = NULL;
932
0
    const UA_SecurityPolicy *tokenSp = NULL;
933
0
    selectEndpointAndTokenPolicy(server, channel, session,
934
0
                                 &req->userIdentityToken,
935
0
                                 &ed, &utp, &tokenSp);
936
0
    if(!ed || !tokenSp) {
937
0
        UA_LOG_WARNING_SESSION(server->config.logging, session,
938
0
                               "ActivateSession: Requested Endpoint/UserTokenPolicy "
939
0
                               "not available");
940
0
        resp->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
941
0
        UA_SESSION_REJECT;
942
0
    }
943
944
    /* Decrypt (or validate the signature) of the UserToken. The DataType of the
945
     * UserToken was already checked in selectEndpointAndTokenPolicy */
946
0
    if(utp->tokenType == UA_USERTOKENTYPE_USERNAME) {
947
        /* If it is a UserNameIdentityToken, the password may be encrypted */
948
0
        UA_UserNameIdentityToken *userToken = (UA_UserNameIdentityToken *)
949
0
           req->userIdentityToken.content.decoded.data;
950
        /* Differentiate between ECC policy decrpytion and RSA decryption.
951
         * With ECC policies, the password is EccEncryptedSecret */
952
0
        if(tokenSp->policyType == UA_SECURITYPOLICYTYPE_ECC) {
953
0
            resp->responseHeader.serviceResult =
954
0
                decryptUserTokenEcc(server->config.logging, session->serverNonce,
955
0
                                    tokenSp, userToken->encryptionAlgorithm,
956
0
                                    &userToken->password);
957
0
        } else {
958
0
            resp->responseHeader.serviceResult =
959
0
            decryptUserToken(server, session, channel, tokenSp,
960
0
                             userToken->encryptionAlgorithm, &userToken->password);
961
0
        }
962
0
    } else if(utp->tokenType == UA_USERTOKENTYPE_CERTIFICATE) {
963
        /* If it is a X509IdentityToken, check the userTokenSignature. Note this
964
         * only validates that the user has the corresponding private key for
965
         * the given user certificate. Checking whether the user certificate is
966
         * trusted has to be implemented in the access control plugin. The
967
         * entire token is forwarded in the call to ActivateSession. */
968
0
        UA_X509IdentityToken* x509token = (UA_X509IdentityToken*)
969
0
            req->userIdentityToken.content.decoded.data;
970
0
        resp->responseHeader.serviceResult =
971
0
            checkActivateSessionX509(server, session, tokenSp,
972
0
                                     x509token, &req->userTokenSignature);
973
0
    } else if(utp->tokenType == UA_USERTOKENTYPE_ISSUEDTOKEN) {
974
        /* IssuedTokens are encrypted */
975
0
       UA_IssuedIdentityToken *issuedToken = (UA_IssuedIdentityToken*)
976
0
           req->userIdentityToken.content.decoded.data;
977
0
       resp->responseHeader.serviceResult = decryptUserToken(
978
0
           server, session, channel, tokenSp, issuedToken->encryptionAlgorithm,
979
0
           &issuedToken->tokenData);
980
0
    } /* else Anonymous */
981
0
    if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
982
0
        UA_SECURITY_REJECT;
983
984
    /* Callback into userland access control */
985
0
    resp->responseHeader.serviceResult = server->config.accessControl.
986
0
        activateSession(server, &server->config.accessControl, ed,
987
0
                        &channel->remoteCertificate, &session->sessionId,
988
0
                        &req->userIdentityToken, &session->context);
989
0
    if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
990
0
        UA_LOG_WARNING_SESSION(server->config.logging, session,
991
0
                               "ActivateSession: The AccessControl "
992
0
                               "plugin denied the activation with the StatusCode %s",
993
0
                               UA_StatusCode_name(resp->responseHeader.serviceResult));
994
0
        UA_SECURITY_REJECT;
995
0
    }
996
997
    /* Attach the session to the currently used channel if the session isn't
998
     * attached to a channel or if the session is activated on a different
999
     * channel than it is attached to. */
1000
0
    if(!session->channel || session->channel != channel) {
1001
        /* Attach the new SecureChannel, the old channel will be detached if present */
1002
0
        UA_Session_attachToSecureChannel(server, session, channel);
1003
0
        UA_LOG_INFO_SESSION(server->config.logging, session,
1004
0
                            "ActivateSession: Session attached to new channel");
1005
0
    }
1006
1007
    /* Generate a new session nonce for the next time ActivateSession is called */
1008
0
    resp->responseHeader.serviceResult = UA_Session_generateNonce(session);
1009
0
    resp->responseHeader.serviceResult |=
1010
0
        UA_ByteString_copy(&session->serverNonce, &resp->serverNonce);
1011
0
    if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
1012
0
        UA_Session_detachFromSecureChannel(server, session);
1013
0
        UA_LOG_WARNING_SESSION(server->config.logging, session,
1014
0
                               "ActivateSession: Could not generate the server nonce");
1015
0
        UA_SESSION_REJECT;
1016
0
    }
1017
1018
    /* Set the Locale */
1019
0
    if(req->localeIdsSize > 0) {
1020
        /* Part 4, §5.6.3.2: This parameter only needs to be specified during
1021
         * the first call to ActivateSession during a single application
1022
         * Session. If it is not specified the Server shall keep using the
1023
         * current localeIds for the Session. */
1024
0
        UA_String *tmpLocaleIds;
1025
0
        resp->responseHeader.serviceResult |=
1026
0
            UA_Array_copy(req->localeIds, req->localeIdsSize,
1027
0
                          (void**)&tmpLocaleIds, &UA_TYPES[UA_TYPES_STRING]);
1028
0
        if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
1029
0
            UA_Session_detachFromSecureChannel(server, session);
1030
0
            UA_LOG_WARNING_SESSION(server->config.logging, session,
1031
0
                                   "ActivateSession: Could not store the "
1032
0
                                   "Session LocaleIds");
1033
0
            UA_SESSION_REJECT;
1034
0
        }
1035
0
        UA_Array_delete(session->localeIds, session->localeIdsSize,
1036
0
                        &UA_TYPES[UA_TYPES_STRING]);
1037
0
        session->localeIds = tmpLocaleIds;
1038
0
        session->localeIdsSize = req->localeIdsSize;
1039
0
    }
1040
1041
    /* Update the Session lifetime */
1042
0
    UA_DateTime now = el->dateTime_now(el);
1043
0
    nowMonotonic = el->dateTime_nowMonotonic(el);
1044
0
    UA_Session_updateLifetime(session, now, nowMonotonic);
1045
1046
    /* If ECC policy, create the new ephemeral key to be returned in the
1047
     * ActivateSession response */
1048
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
1049
0
    if(sp && sp->policyType == UA_SECURITYPOLICYTYPE_ECC) {
1050
0
        resp->responseHeader.serviceResult =
1051
0
            addEphemeralKeyAdditionalHeader(server, sp, channel->channelContext,
1052
0
                                            &resp->responseHeader.additionalHeader);
1053
0
        if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
1054
0
            UA_SECURITY_REJECT;
1055
0
        UA_LOG_DEBUG(server->config.logging, UA_LOGCATEGORY_SESSION,
1056
0
                     "[ActivateSession] Ephemeral Key created");
1057
0
    }
1058
1059
    /* Activate the session */
1060
0
    if(!session->activated) {
1061
0
        session->activated = true;
1062
0
        server->activeSessionCount++;
1063
0
        server->serverDiagnosticsSummary.cumulatedSessionCount++;
1064
0
    }
1065
1066
    /* Store the ClientUserId. tokenType can be NULL for the anonymous user. */
1067
0
    UA_String_clear(&session->clientUserIdOfSession);
1068
0
    const UA_DataType *tokenType = req->userIdentityToken.content.decoded.type;
1069
0
    if(tokenType == &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]) {
1070
0
        const UA_UserNameIdentityToken *userToken = (UA_UserNameIdentityToken*)
1071
0
            req->userIdentityToken.content.decoded.data;
1072
0
        UA_String_copy(&userToken->userName, &session->clientUserIdOfSession);
1073
0
    } else if(tokenType == &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]) {
1074
0
        UA_X509IdentityToken* userCertToken = (UA_X509IdentityToken*)
1075
0
            req->userIdentityToken.content.decoded.data;
1076
0
        UA_CertificateUtils_getSubjectName(&session->clientUserIdOfSession,
1077
0
                                           &userCertToken->certificateData);
1078
0
    } else {
1079
        /* TODO: Handle issued token */
1080
0
    }
1081
1082
0
#ifdef UA_ENABLE_DIAGNOSTICS
1083
    /* Add the ClientUserId to the diagnostics history. Ignoring errors in _appendCopy. */
1084
0
    UA_SessionSecurityDiagnosticsDataType *ssd = &session->securityDiagnostics;
1085
0
    UA_Array_appendCopy((void**)&ssd->clientUserIdHistory,
1086
0
                        &ssd->clientUserIdHistorySize,
1087
0
                        &ssd->clientUserIdOfSession,
1088
0
                        &UA_TYPES[UA_TYPES_STRING]);
1089
1090
    /* Store the auth mechanism */
1091
0
    UA_String_clear(&ssd->authenticationMechanism);
1092
0
    switch(utp->tokenType) {
1093
0
    case UA_USERTOKENTYPE_ANONYMOUS:
1094
0
        ssd->authenticationMechanism = UA_STRING_ALLOC("Anonymous"); break;
1095
0
    case UA_USERTOKENTYPE_USERNAME:
1096
0
        ssd->authenticationMechanism = UA_STRING_ALLOC("UserName"); break;
1097
0
    case UA_USERTOKENTYPE_CERTIFICATE:
1098
0
        ssd->authenticationMechanism = UA_STRING_ALLOC("Certificate"); break;
1099
0
    case UA_USERTOKENTYPE_ISSUEDTOKEN:
1100
0
        ssd->authenticationMechanism = UA_STRING_ALLOC("IssuedToken"); break;
1101
0
    default: break;
1102
0
    }
1103
0
#endif
1104
1105
    /* Notify the application */
1106
0
    notifySession(server, session, UA_APPLICATIONNOTIFICATIONTYPE_SESSION_ACTIVATED);
1107
1108
    /* Log the user for which the Session was activated */
1109
0
    UA_LOG_INFO_SESSION(server->config.logging, session,
1110
0
                        "ActivateSession: Session activated with ClientUserId \"%S\"",
1111
0
                        session->clientUserIdOfSession);
1112
0
}
1113
1114
void
1115
Service_CloseSession(UA_Server *server, UA_SecureChannel *channel,
1116
                     const UA_CloseSessionRequest *request,
1117
0
                     UA_CloseSessionResponse *response) {
1118
0
    UA_LOCK_ASSERT(&server->serviceMutex);
1119
1120
    /* Part 4, 5.6.4: When the CloseSession Service is called before the Session
1121
     * is successfully activated, the Server shall reject the request if the
1122
     * SecureChannel is not the same as the one associated with the
1123
     * CreateSession request.
1124
     *
1125
     * A non-activated Session is already bound to the SecureChannel that
1126
     * created the Session. */
1127
0
    UA_Session *session = NULL;
1128
0
    response->responseHeader.serviceResult =
1129
0
        getBoundSession(server, channel, &request->requestHeader.authenticationToken, &session);
1130
0
    if(!session && response->responseHeader.serviceResult == UA_STATUSCODE_GOOD)
1131
0
        response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
1132
0
    if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
1133
0
        UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
1134
0
                               "CloseSession: No Session activated to the SecureChannel");
1135
0
        return;
1136
0
    }
1137
1138
0
    UA_assert(session); /* Assured by the previous section */
1139
0
    UA_LOG_INFO_SESSION(server->config.logging, session, "Closing the Session");
1140
1141
0
#ifdef UA_ENABLE_SUBSCRIPTIONS
1142
    /* If Subscriptions are not deleted, detach them from the Session */
1143
0
    if(!request->deleteSubscriptions) {
1144
0
        UA_Subscription *sub, *sub_tmp;
1145
0
        TAILQ_FOREACH_SAFE(sub, &session->subscriptions, sessionListEntry, sub_tmp) {
1146
0
            UA_LOG_INFO_SUBSCRIPTION(server->config.logging, sub,
1147
0
                                     "Detaching the Subscription from the Session");
1148
0
            UA_Session_detachSubscription(server, session, sub, true);
1149
0
        }
1150
0
    }
1151
0
#endif
1152
1153
    /* Remove the sesison */
1154
0
    UA_Session_remove(server, session, UA_SHUTDOWNREASON_CLOSE);
1155
0
}
1156
1157
UA_Boolean
1158
Service_Cancel(UA_Server *server, UA_Session *session,
1159
0
               const UA_CancelRequest *request, UA_CancelResponse *response) {
1160
    /* If multithreading is disabled, then there are no async services. If all
1161
     * services are answered "right away", then there are no services that can
1162
     * be cancelled. */
1163
0
    response->cancelCount = UA_AsyncManager_cancel(server, session, request->requestHandle);
1164
1165
    /* Publish requests for Subscriptions are stored separately */
1166
0
#ifdef UA_ENABLE_SUBSCRIPTIONS
1167
0
    UA_PublishResponseEntry *pre, *pre_tmp;
1168
0
    UA_PublishResponseEntry *prev = NULL;
1169
0
    SIMPLEQ_FOREACH_SAFE(pre, &session->responseQueue, listEntry, pre_tmp) {
1170
        /* Skip entry and set as the previous entry that is kept in the list */
1171
0
        if(pre->response.responseHeader.requestHandle != request->requestHandle) {
1172
0
            prev = pre;
1173
0
            continue;
1174
0
        }
1175
1176
        /* Dequeue */
1177
0
        if(prev)
1178
0
            SIMPLEQ_REMOVE_AFTER(&session->responseQueue, prev, listEntry);
1179
0
        else
1180
0
            SIMPLEQ_REMOVE_HEAD(&session->responseQueue, listEntry);
1181
0
        session->responseQueueSize--;
1182
1183
        /* Send response and clean up */
1184
0
        response->responseHeader.serviceResult = UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT;
1185
0
        sendResponse(server, session->channel, pre->requestId, (UA_Response *)response,
1186
0
                     &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]);
1187
0
        UA_PublishResponse_clear(&pre->response);
1188
0
        UA_free(pre);
1189
1190
        /* Increase the CancelCount */
1191
0
        response->cancelCount++;
1192
0
    }
1193
0
#endif
1194
1195
    return true;
1196
0
}