Coverage Report

Created: 2026-11-05 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open62541_15/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
 *    Copyright 2026 (c) o6 Automation GmbH (Author: Julius Pfrommer)
16
 *    Copyright 2026 (c) o6 Automation GmbH (Author: Andreas Ebner)
17
 */
18
19
#include "ua_server_internal.h"
20
#include "ua_services.h"
21
22
void
23
notifySession(UA_Server *server, UA_Session *session,
24
27.1k
              UA_ApplicationNotificationType type) {
25
    /* Nothing to do */
26
27.1k
    if(!server->config.globalNotificationCallback &&
27
27.1k
       !server->config.sessionNotificationCallback)
28
27.1k
        return;
29
30
    /* Set up the payload */
31
0
    size_t payloadSize = 6 + session->attributes.mapSize;
32
0
    UA_STACKARRAY(UA_KeyValuePair, payloadData, payloadSize);
33
0
    UA_KeyValueMap payloadMap = {payloadSize, payloadData};
34
0
    payloadData[0].key = UA_QUALIFIEDNAME(0, "session-id");
35
0
    UA_Variant_setScalar(&payloadData[0].value, &session->sessionId,
36
0
                         &UA_TYPES[UA_TYPES_NODEID]);
37
0
    payloadData[1].key = UA_QUALIFIEDNAME(0, "securechannel-id");
38
0
    UA_UInt32 secureChannelId = 0;
39
0
    if(session->channel)
40
0
        secureChannelId = session->channel->securityToken.channelId;
41
0
    UA_Variant_setScalar(&payloadData[1].value, &secureChannelId,
42
0
                         &UA_TYPES[UA_TYPES_UINT32]);
43
0
    payloadData[2].key = UA_QUALIFIEDNAME(0, "session-name");
44
0
    UA_Variant_setScalar(&payloadData[2].value, &session->sessionName,
45
0
                         &UA_TYPES[UA_TYPES_STRING]);
46
0
    payloadData[3].key = UA_QUALIFIEDNAME(0, "client-description");
47
0
    UA_Variant_setScalar(&payloadData[3].value, &session->clientDescription,
48
0
                         &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
49
0
    payloadData[4].key = UA_QUALIFIEDNAME(0, "client-user-id");
50
0
    UA_Variant_setScalar(&payloadData[4].value, &session->clientUserIdOfSession,
51
0
                         &UA_TYPES[UA_TYPES_STRING]);
52
0
    payloadData[5].key = UA_QUALIFIEDNAME(0, "locale-ids");
53
0
    UA_Variant_setArray(&payloadData[5].value, session->localeIds,
54
0
                        session->localeIdsSize, &UA_TYPES[UA_TYPES_STRING]);
55
56
0
    if(session->attributes.mapSize)
57
0
        memcpy(&payloadData[6], session->attributes.map,
58
0
               sizeof(UA_KeyValuePair) * session->attributes.mapSize);
59
60
    /* Call the notification callback */
61
0
    if(server->config.sessionNotificationCallback)
62
0
        server->config.sessionNotificationCallback(server, type, payloadMap);
63
0
    if(server->config.globalNotificationCallback)
64
0
        server->config.globalNotificationCallback(server, type, payloadMap);
65
0
}
66
67
/* Delayed callback to free the session memory */
68
static void
69
8.56k
removeSessionCallback(UA_Server *server, session_list_entry *entry) {
70
8.56k
    lockServer(server);
71
8.56k
    UA_Session_clear(&entry->session, server);
72
8.56k
    unlockServer(server);
73
8.56k
    UA_free(entry);
74
8.56k
}
75
76
void
77
UA_Session_remove(UA_Server *server, UA_Session *session,
78
8.56k
                  UA_ShutdownReason shutdownReason) {
79
8.56k
    UA_LOCK_ASSERT(&server->serviceMutex);
80
81
    /* When the session times out, detach
82
     * subscriptions so they can be recovered via TransferSubscriptions. */
83
8.56k
#ifdef UA_ENABLE_SUBSCRIPTIONS
84
8.56k
    UA_Subscription *sub, *tempsub;
85
8.56k
    TAILQ_FOREACH_SAFE(sub, &session->subscriptions, sessionListEntry, tempsub) {
86
154
        if(shutdownReason == UA_SHUTDOWNREASON_TIMEOUT) {
87
0
            UA_LOG_INFO_SUBSCRIPTION(server->config.logging, sub,
88
0
                                     "Detaching the Subscription from the timed-out Session");
89
0
            UA_Session_detachSubscription(server, session, sub, true);
90
154
        } else {
91
154
            UA_Subscription_delete(server, sub);
92
154
        }
93
154
    }
94
95
8.56k
    UA_PublishResponseEntry *entry;
96
8.56k
    while((entry = UA_Session_dequeuePublishReq(session))) {
97
0
        UA_PublishResponse_clear(&entry->response);
98
0
        UA_free(entry);
99
0
    }
100
8.56k
#endif
101
102
    /* Callback into userland access control */
103
8.56k
    if(server->config.accessControl.closeSession) {
104
8.56k
        server->config.accessControl.
105
8.56k
            closeSession(server, &server->config.accessControl,
106
8.56k
                         &session->sessionId, session->context);
107
8.56k
    }
108
109
    /* Detach the Session from the SecureChannel */
110
8.56k
    UA_Session_detachFromSecureChannel(server, session);
111
112
    /* Deactivate the session */
113
8.56k
    if(session->activated) {
114
4.90k
        session->activated = false;
115
4.90k
        server->activeSessionCount--;
116
4.90k
    }
117
118
    /* Detach the session from the session manager and make the capacity
119
     * available */
120
8.56k
    session_list_entry *sentry = container_of(session, session_list_entry, session);
121
8.56k
    LIST_REMOVE(sentry, pointers);
122
8.56k
    server->sessionCount--;
123
124
8.56k
    switch(shutdownReason) {
125
8.47k
    case UA_SHUTDOWNREASON_CLOSE:
126
8.52k
    case UA_SHUTDOWNREASON_PURGE:
127
8.52k
        break;
128
0
    case UA_SHUTDOWNREASON_TIMEOUT:
129
0
        server->serverDiagnosticsSummary.sessionTimeoutCount++;
130
0
        break;
131
0
    case UA_SHUTDOWNREASON_REJECT:
132
0
        server->serverDiagnosticsSummary.rejectedSessionCount++;
133
0
        break;
134
0
    case UA_SHUTDOWNREASON_SECURITYREJECT:
135
0
        server->serverDiagnosticsSummary.securityRejectedSessionCount++;
136
0
        break;
137
41
    case UA_SHUTDOWNREASON_ABORT:
138
41
        server->serverDiagnosticsSummary.sessionAbortCount++;
139
41
        break;
140
0
    default:
141
0
        UA_assert(false);
142
0
        break;
143
8.56k
    }
144
145
    /* Notify the application */
146
8.56k
    notifySession(server, session, UA_APPLICATIONNOTIFICATIONTYPE_SESSION_CLOSED);
147
148
    /* Add a delayed callback to remove the session when the currently
149
     * scheduled jobs have completed */
150
8.56k
    sentry->cleanupCallback.callback = (UA_Callback)removeSessionCallback;
151
8.56k
    sentry->cleanupCallback.application = server;
152
8.56k
    sentry->cleanupCallback.context = sentry;
153
8.56k
    UA_EventLoop *el = server->config.eventLoop;
154
8.56k
    el->addDelayedCallback(el, &sentry->cleanupCallback);
155
8.56k
}
156
157
void
158
0
cleanupSessions(UA_Server *server, UA_DateTime nowMonotonic) {
159
0
    UA_LOCK_ASSERT(&server->serviceMutex);
160
0
    session_list_entry *sentry, *temp;
161
0
    LIST_FOREACH_SAFE(sentry, &server->sessions, pointers, temp) {
162
        /* Session has timed out? */
163
0
        if(sentry->session.validTill >= nowMonotonic)
164
0
            continue;
165
0
        UA_LOG_INFO_SESSION(server->config.logging, &sentry->session,
166
0
                            "Session has timed out");
167
0
        UA_Session_remove(server, &sentry->session, UA_SHUTDOWNREASON_TIMEOUT);
168
0
    }
169
0
}
170
171
/************/
172
/* Services */
173
/************/
174
175
UA_Session *
176
3.52k
getSessionByToken(UA_Server *server, const UA_NodeId *token) {
177
3.52k
    UA_LOCK_ASSERT(&server->serviceMutex);
178
179
3.52k
    session_list_entry *current = NULL;
180
3.52k
    LIST_FOREACH(current, &server->sessions, pointers) {
181
        /* Token does not match */
182
1.91k
        if(!UA_NodeId_equal(&current->session.authenticationToken, token))
183
419
            continue;
184
185
        /* Session has timed out */
186
1.49k
        UA_EventLoop *el = server->config.eventLoop;
187
1.49k
        UA_DateTime now = el->dateTime_nowMonotonic(el);
188
1.49k
        if(now > current->session.validTill) {
189
40
            UA_LOG_WARNING_SESSION(server->config.logging, &current->session,
190
40
                                   "Client tries to use a session that has timed out");
191
40
            return NULL;
192
40
        }
193
194
1.45k
        return &current->session;
195
1.49k
    }
196
197
2.02k
    return NULL;
198
3.52k
}
199
200
UA_Session *
201
2.80k
getSessionById(UA_Server *server, const UA_NodeId *sessionId) {
202
2.80k
    UA_LOCK_ASSERT(&server->serviceMutex);
203
204
    /* A NULL sessionId is a programming error from the public API
205
     * (UA_Server_closeSession) or from an internal caller that has
206
     * no session id. Treat it as "not found" so callers like
207
     * UA_Server_closeSession can return BADSESSIONIDINVALID instead
208
     * of dereferencing NULL inside UA_NodeId_equal. */
209
2.80k
    if(!sessionId)
210
0
        return NULL;
211
212
2.80k
    session_list_entry *current = NULL;
213
2.80k
    LIST_FOREACH(current, &server->sessions, pointers) {
214
        /* Token does not match */
215
2.80k
        if(!UA_NodeId_equal(&current->session.sessionId, sessionId))
216
0
            continue;
217
218
        /* Session has timed out */
219
2.80k
        UA_EventLoop *el = server->config.eventLoop;
220
2.80k
        UA_DateTime now = el->dateTime_nowMonotonic(el);
221
2.80k
        if(now > current->session.validTill) {
222
0
            UA_LOG_WARNING_SESSION(server->config.logging, &current->session,
223
0
                                   "Client tries to use a session that has timed out");
224
0
            return NULL;
225
0
        }
226
227
2.80k
        return &current->session;
228
2.80k
    }
229
230
0
    if(UA_NodeId_equal(sessionId, &server->adminSession.sessionId))
231
0
        return &server->adminSession;
232
233
0
    return NULL;
234
0
}
235
236
static UA_StatusCode
237
signCreateSessionResponse(UA_Server *server, UA_SecureChannel *channel,
238
                          const UA_CreateSessionRequest *request,
239
4.66k
                          UA_CreateSessionResponse *response) {
240
4.66k
    if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
241
4.66k
       channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
242
4.66k
        return UA_STATUSCODE_GOOD;
243
244
0
    const UA_SecurityPolicy *sp = channel->securityPolicy;
245
0
    void *cc = channel->channelContext;
246
0
    UA_SignatureData *signatureData = &response->serverSignature;
247
248
    /* Prepare the signature */
249
0
    const UA_SecurityPolicySignatureAlgorithm *signAlg = &sp->asymSignatureAlgorithm;
250
0
    size_t signatureSize = signAlg->getLocalSignatureSize(sp, cc);
251
0
    UA_StatusCode retval = UA_STATUSCODE_GOOD;
252
    /* OPC UA Part 4 v1.05.07: for SecurityPolicies with
253
     * secureChannelEnhancements = true, the algorithm field in
254
     * SignatureData shall be NULL or empty and receivers shall
255
     * ignore the value. */
256
0
    if(!UA_SecurityPolicy_isEnhancedSecurity(sp))
257
0
        retval = UA_String_copy(&signAlg->uri, &signatureData->algorithm);
258
0
    retval |= UA_ByteString_allocBuffer(&signatureData->signature, signatureSize);
259
0
    if(retval != UA_STATUSCODE_GOOD)
260
0
        return retval;
261
262
    /* Build the data to sign. */
263
0
    UA_ByteString dataToSign = UA_BYTESTRING_NULL;
264
0
    if(UA_SecurityPolicy_isEnhancedSecurity(sp)) {
265
        /* Channel-bound v1.05.07 signature (see the cert-role table at
266
         * UA_SecureChannel_buildCreateSessionSignatureData). */
267
0
        retval = UA_SecureChannel_buildCreateSessionSignatureData(
268
0
            channel, &request->clientNonce, &response->serverNonce,
269
0
            &sp->localCertificate, &channel->remoteCertificate, &dataToSign);
270
0
    } else {
271
0
        retval = UA_ByteString_allocBuffer(&dataToSign,
272
0
            request->clientCertificate.length + request->clientNonce.length);
273
0
        if(retval == UA_STATUSCODE_GOOD) {
274
0
            memcpy(dataToSign.data, request->clientCertificate.data,
275
0
                   request->clientCertificate.length);
276
0
            memcpy(dataToSign.data + request->clientCertificate.length,
277
0
                   request->clientNonce.data, request->clientNonce.length);
278
0
        }
279
0
    }
280
0
    if(retval != UA_STATUSCODE_GOOD)
281
0
        return retval; /* signatureData->signature is cleaned up with the response */
282
283
0
    retval = signAlg->sign(sp, cc, &dataToSign, &signatureData->signature);
284
285
    /* Clean up */
286
0
    UA_ByteString_clear(&dataToSign);
287
0
    return retval;
288
0
}
289
290
static UA_StatusCode
291
createCheckSessionAuthSecurityPolicyContext(UA_Server *server, UA_Session *session,
292
                                            UA_SecurityPolicy *sp, const char *logPrefix,
293
0
                                            const UA_ByteString remoteCertificate) {
294
    /* The session is already "taken" by a different SecurityPolicy */
295
0
    if(session->sessionSp && session->sessionSp != sp) {
296
0
        UA_LOG_ERROR_SESSION(server->config.logging, session,
297
0
                             "%s: Cannot instantiate SecurityPolicyContext %S for the "
298
0
                             "Session. A different SecurityPolicy %S is "
299
0
                             "already in place", logPrefix, sp->policyUri,
300
0
                             session->sessionSp->policyUri);
301
0
        return UA_STATUSCODE_BADSECURITYPOLICYREJECTED;
302
0
    }
303
0
    session->sessionSp = sp;
304
305
    /* Existing SecurityPolicy context, check for the identical remote
306
     * certificate */
307
0
    UA_StatusCode res = UA_STATUSCODE_GOOD;
308
0
    if(session->sessionSpContext) {
309
0
        res = sp->compareCertificate(sp, session->sessionSpContext, &remoteCertificate);
310
0
        if(res != UA_STATUSCODE_GOOD) {
311
0
            UA_LOG_ERROR_SESSION(server->config.logging, session,
312
0
                                 "%s: The client tries to use a different certificate "
313
0
                                 "for authentication", logPrefix);
314
0
        }
315
0
        return res;
316
0
    }
317
318
    /* Instantiate a new context if we can. Otherwise operate without a channel
319
     * context. That is possible for asymmetric decryption with RSA which
320
     * requires only the local certificate. But ECC won't work. */
321
0
    if(remoteCertificate.length > 0) {
322
0
        res = sp->newChannelContext(sp, &remoteCertificate,
323
0
                                    &session->sessionSpContext);
324
0
        if(res != UA_STATUSCODE_GOOD) {
325
0
            UA_LOG_ERROR_SESSION(server->config.logging, session,
326
0
                                 "%s: Could not use the supplied certificate "
327
0
                                 "to instantiate the SecurityPolicy %S for the "
328
0
                                 "validation of the UserIdentityToken",
329
0
                                 logPrefix, sp->policyUri);
330
0
        }
331
0
    }
332
0
    return res;
333
0
}
334
335
/* The client requests a server ephemeral ECDH key by adding an "ECDHPolicyUri"
336
 * entry to the request's AdditionalHeader (an AdditionalParametersType). The
337
 * server must return its ECDHKey only when this was requested. */
338
static UA_Boolean
339
0
clientRequestedEphemeralKey(const UA_ExtensionObject *additionalHeader) {
340
0
    if(additionalHeader->encoding != UA_EXTENSIONOBJECT_DECODED &&
341
0
       additionalHeader->encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE)
342
0
        return false;
343
0
    if(additionalHeader->content.decoded.type !=
344
0
       &UA_TYPES[UA_TYPES_ADDITIONALPARAMETERSTYPE])
345
0
        return false;
346
0
    const UA_AdditionalParametersType *ap = (const UA_AdditionalParametersType*)
347
0
        additionalHeader->content.decoded.data;
348
0
    UA_String ecdhPolicyUri = UA_STRING("ECDHPolicyUri");
349
0
    for(size_t i = 0; i < ap->parametersSize; i++) {
350
0
        if(ap->parameters[i].key.namespaceIndex == 0 &&
351
0
           UA_String_equal(&ap->parameters[i].key.name, &ecdhPolicyUri))
352
0
            return true;
353
0
    }
354
0
    return false;
355
0
}
356
357
static UA_StatusCode
358
addEphemeralKeyAdditionalHeader(UA_Server *server, UA_Session *session,
359
0
                                UA_ExtensionObject *ah) {
360
0
    UA_assert(session->sessionSp && session->sessionSpContext);
361
0
    UA_SecurityPolicy *sp = session->sessionSp;
362
0
    void *spContext = session->sessionSpContext;
363
364
    /* Allocate additional parameters */
365
0
    UA_AdditionalParametersType *ap = UA_AdditionalParametersType_new();
366
0
    if(!ap)
367
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
368
369
    /* Set the additional parameters in the additional header. They also get
370
     * cleaned up from there in the error case. */
371
0
    UA_ExtensionObject_setValue(ah, ap, &UA_TYPES[UA_TYPES_ADDITIONALPARAMETERSTYPE]);
372
373
    /* UA_KeyValueMap has the identical layout. And better helper methods. */
374
0
    UA_KeyValueMap *map = (UA_KeyValueMap*)ap;
375
376
    /* Add the PolicyUri to the map */
377
0
    UA_StatusCode res =
378
0
        UA_KeyValueMap_setScalar(map, UA_QUALIFIEDNAME(0, "ECDHPolicyUri"),
379
0
                                 &sp->policyUri, &UA_TYPES[UA_TYPES_STRING]);
380
0
    if(res != UA_STATUSCODE_GOOD)
381
0
        return res;
382
383
    /* Initialize the EphemeralKey on the stack */
384
0
    UA_EphemeralKeyType ephKey;
385
0
    UA_EphemeralKeyType_init(&ephKey);
386
387
    /* Allocate the ephemeral key buffer to the exact size of the ephemeral key
388
     * for the used ECC policy so that the nonce generation function knows that
389
     * it needs to generate an ephemeral key and not some other random byte
390
     * string.
391
     *
392
     * TODO: There should be a more stable way to signal the generation of an
393
     * ephemeral key */
394
0
    res = UA_ByteString_allocBuffer(&ephKey.publicKey, sp->nonceLength);
395
0
    if(res != UA_STATUSCODE_GOOD)
396
0
        return res;
397
398
    /* Allocate the signature buffer */
399
0
    size_t signatureSize =
400
0
        sp->asymSignatureAlgorithm.getLocalSignatureSize(sp, spContext);
401
0
    res = UA_ByteString_allocBuffer(&ephKey.signature, signatureSize);
402
0
    if(res != UA_STATUSCODE_GOOD) {
403
0
        UA_EphemeralKeyType_clear(&ephKey);
404
0
        return res;
405
0
    }
406
407
    /* Generate the ephemeral key and signature */
408
0
    ephKey.publicKey.data[0] = 'e';
409
0
    ephKey.publicKey.data[1] = 'p';
410
0
    ephKey.publicKey.data[2] = 'h';
411
0
    res |= sp->generateNonce(sp, spContext, &ephKey.publicKey);
412
0
    res |= sp->asymSignatureAlgorithm.sign(sp, spContext, &ephKey.publicKey,
413
0
                                           &ephKey.signature);
414
415
    /* Add the EphemeralKey to the map (deep copy) */
416
0
    if(res == UA_STATUSCODE_GOOD)
417
0
        res = UA_KeyValueMap_setScalar(map, UA_QUALIFIEDNAME(0, "ECDHKey"),
418
0
                                       &ephKey, &UA_TYPES[UA_TYPES_EPHEMERALKEYTYPE]);
419
0
    UA_EphemeralKeyType_clear(&ephKey);
420
0
    return res;
421
0
}
422
423
/* Remove the oldest Session that has not completed ActivateSession yet. Such
424
 * a Session is not yet an authenticated client and, like an un-activated
425
 * Session pinning a SecureChannel, must not be allowed to exhaust the Session
426
 * table and block CreateSession for everyone else. The list is ordered
427
 * newest-first, so keep scanning to the end to find the oldest match. */
428
static UA_Boolean
429
0
purgeOldestUnactivatedSession(UA_Server *server) {
430
0
    session_list_entry *sentry, *oldest = NULL;
431
0
    LIST_FOREACH(sentry, &server->sessions, pointers) {
432
0
        if(!sentry->session.activated)
433
0
            oldest = sentry;
434
0
    }
435
0
    if(!oldest)
436
0
        return false;
437
0
    UA_LOG_INFO_SESSION(server->config.logging, &oldest->session,
438
0
                        "Session was purged since maxSessions was reached "
439
0
                        "and the Session was not yet activated");
440
0
    UA_Session_remove(server, &oldest->session, UA_SHUTDOWNREASON_PURGE);
441
0
    return true;
442
0
}
443
444
/* Creates and adds a session. But it is not yet attached to a secure channel. */
445
UA_StatusCode
446
UA_Session_create(UA_Server *server, UA_SecureChannel *channel,
447
8.56k
                  const UA_CreateSessionRequest *request, UA_Session **session) {
448
8.56k
    UA_LOCK_ASSERT(&server->serviceMutex);
449
450
8.56k
    if(server->sessionCount >= server->config.maxSessions &&
451
0
       !purgeOldestUnactivatedSession(server)) {
452
0
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
453
0
                             "CreateSession: Could not create a Session - "
454
0
                             "Server limits reached");
455
0
        return UA_STATUSCODE_BADTOOMANYSESSIONS;
456
0
    }
457
458
8.56k
    session_list_entry *newentry = (session_list_entry*)
459
8.56k
        UA_malloc(sizeof(session_list_entry));
460
8.56k
    if(!newentry)
461
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
462
463
    /* Initialize the Session */
464
8.56k
    UA_Session_init(&newentry->session);
465
8.56k
    newentry->session.sessionId = UA_NODEID_GUID(1, UA_Guid_random());
466
8.56k
    newentry->session.authenticationToken = UA_NODEID_GUID(1, UA_Guid_secureRandom());
467
468
8.56k
    newentry->session.timeout = server->config.maxSessionTimeout;
469
8.56k
    if(request->requestedSessionTimeout <= server->config.maxSessionTimeout &&
470
6.77k
       request->requestedSessionTimeout > 0)
471
4.88k
        newentry->session.timeout = request->requestedSessionTimeout;
472
473
    /* Attach the session to the channel. But don't activate for now. */
474
8.56k
    if(channel)
475
8.56k
        UA_Session_attachToSecureChannel(server, &newentry->session, channel);
476
477
8.56k
    UA_EventLoop *el = server->config.eventLoop;
478
8.56k
    UA_DateTime now = el->dateTime_now(el);
479
8.56k
    UA_DateTime nowMonotonic = el->dateTime_nowMonotonic(el);
480
8.56k
    UA_Session_updateLifetime(&newentry->session, now, nowMonotonic);
481
482
    /* Add to the server */
483
8.56k
    LIST_INSERT_HEAD(&server->sessions, newentry, pointers);
484
8.56k
    server->sessionCount++;
485
486
    /* Notify the application */
487
8.56k
    notifySession(server, &newentry->session,
488
8.56k
                  UA_APPLICATIONNOTIFICATIONTYPE_SESSION_CREATED);
489
490
    /* Return */
491
8.56k
    *session = &newentry->session;
492
8.56k
    return UA_STATUSCODE_GOOD;
493
8.56k
}
494
495
void
496
Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
497
                      const UA_CreateSessionRequest *request,
498
4.66k
                      UA_CreateSessionResponse *response) {
499
4.66k
    UA_LOCK_ASSERT(&server->serviceMutex);
500
4.66k
    UA_LOG_DEBUG_CHANNEL(server->config.logging, channel, "CreateSession");
501
502
4.66k
    void *cc = channel->channelContext;
503
4.66k
    UA_SecurityPolicy *sp = channel->securityPolicy;
504
4.66k
    UA_ResponseHeader *rh = &response->responseHeader;
505
4.66k
    UA_assert(sp != NULL);
506
507
    /* Part 4: In many cases, the Certificates used to establish the
508
     * SecureChannel will be the ApplicationInstanceCertificates. However, some
509
     * Communication Stacks might not support Certificates that are specific to
510
     * a single application. Instead, they expect all communication to be
511
     * secured with a Certificate specific to a user or the entire machine. For
512
     * this reason, OPC UA Applications will need to exchange their
513
     * ApplicationInstanceCertificates when creating a Session.
514
     *
515
     * However Part 6 requires that the asymmetric algorithm security header
516
     * contains the "X.509 v3 Certificate assigned to the sending application
517
     * Instance." So we assume that the SecureChannel was created with the same
518
     * ApplicationInstanceCertificate. This may change in the future for
519
     * additional transport types. */
520
4.66k
    if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
521
4.66k
       channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
522
523
        /* Compare the clientCertificate with the remoteCertificate of the
524
         * channel.
525
         *
526
         * Both the clientCertificate of this request and the remoteCertificate
527
         * of the channel may contain a partial or a complete certificate chain.
528
         * The compareCertificate function will compare the first certificate of
529
         * each chain. The end certificate shall be located first in the chain
530
         * according to the OPC UA specification Part 6 (1.04), chapter 6.2.3.*/
531
0
        UA_StatusCode res = sp->compareCertificate(sp, cc, &request->clientCertificate);
532
0
        if(res != UA_STATUSCODE_GOOD) {
533
0
            UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
534
0
                                 "CreateSession: The client uses a different "
535
0
                                 "certificate for SecureChannel and Session");
536
0
            server->serverDiagnosticsSummary.securityRejectedSessionCount++;
537
0
            server->serverDiagnosticsSummary.rejectedSessionCount++;
538
0
            rh->serviceResult = UA_STATUSCODE_BADCERTIFICATEINVALID;
539
0
            return;
540
0
        }
541
0
    }
542
543
    /* Check the client certificate and ApplicationDescription. It was already
544
     * checked for the SecureChannel. But here we use the Session
545
     * CertificateGroup and we now also have the ApplicationDescription to check
546
     * the ApplicationUri.
547
     *
548
     * Per OPC UA Part 4, Section 5.6.2.2: "If the securityPolicyUri is None,
549
     * the Server shall ignore the ApplicationInstanceCertificate." */
550
4.66k
    if(channel->securityPolicy->policyType == UA_SECURITYPOLICYTYPE_NONE) {
551
4.66k
        if(request->clientCertificate.length > 0) {
552
29
            UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
553
29
                                   "CreateSession: Ignoring client certificate "
554
29
                                   "on SecurityPolicy None (Part 4, 5.6.2.2)");
555
29
        }
556
4.66k
    } else if(request->clientCertificate.length > 0) {
557
0
        rh->serviceResult =
558
0
            validateCertificate(server, &server->config.secureChannelPKI,
559
0
                                channel, NULL, "CreateSession",
560
0
                                &request->clientDescription,
561
0
                                request->clientCertificate);
562
0
        if(rh->serviceResult != UA_STATUSCODE_GOOD) {
563
0
            server->serverDiagnosticsSummary.securityRejectedSessionCount++;
564
0
            server->serverDiagnosticsSummary.rejectedSessionCount++;
565
0
            return;
566
0
        }
567
0
    }
568
569
    /* According to the spec, the (session) ClientNonce needs a length between
570
     * 32 and 128 bytes inclusive. This is the application nonce length and is
571
     * independent of the SecurityPolicy's SecureChannel nonce length (for ECC
572
     * policies that is the 64-byte ephemeral key, which is NOT the session
573
     * nonce). */
574
4.66k
    if(channel->securityPolicy->policyType != UA_SECURITYPOLICYTYPE_NONE &&
575
0
       (request->clientNonce.length < 32 || request->clientNonce.length > 128)) {
576
0
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
577
0
                             "CreateSession: The nonce provided by the client "
578
0
                             "has the wrong length");
579
0
        server->serverDiagnosticsSummary.securityRejectedSessionCount++;
580
0
        server->serverDiagnosticsSummary.rejectedSessionCount++;
581
0
        rh->serviceResult = UA_STATUSCODE_BADNONCEINVALID;
582
0
        return;
583
0
    }
584
585
    /* Create the Session */
586
4.66k
    UA_Session *newSession = NULL;
587
4.66k
    rh->serviceResult = UA_Session_create(server, channel, request, &newSession);
588
4.66k
    if(rh->serviceResult != UA_STATUSCODE_GOOD) {
589
0
        server->serverDiagnosticsSummary.rejectedSessionCount++;
590
0
        return;
591
0
    }
592
593
    /* If the session name is empty, use the generated SessionId */
594
4.66k
    rh->serviceResult |= UA_String_copy(&request->sessionName,
595
4.66k
                                        &newSession->sessionName);
596
4.66k
    if(newSession->sessionName.length == 0)
597
4.58k
        rh->serviceResult |= UA_NodeId_print(&newSession->sessionId,
598
4.58k
                                             &newSession->sessionName);
599
600
    /* Configure the Session */
601
4.66k
    newSession->maxResponseMessageSize = request->maxResponseMessageSize;
602
4.66k
    newSession->maxRequestMessageSize = channel->config.localMaxMessageSize;
603
4.66k
    rh->serviceResult |= UA_ApplicationDescription_copy(&request->clientDescription,
604
4.66k
                                                        &newSession->clientDescription);
605
606
    /* The SecureChannel certificate must correspond to the client's
607
     * ApplicationCertificate. But for unencrypted SecureChannels we store the
608
     * certificate directly in the Session. We need it later when an encrypted
609
     * UserIdentityToken is sent over an unencrypted SecureChannel. */
610
4.66k
    if(channel->remoteCertificate.length == 0)
611
4.66k
        rh->serviceResult |= UA_ByteString_copy(&request->clientCertificate,
612
4.66k
                                                &newSession->clientCertificate);
613
614
    /* Retain the clientNonce for the v1.05.07 channel-bound
615
     * ActivateSession ClientSignature verification
616
     * (secureChannelEnhancements). */
617
4.66k
    rh->serviceResult |= UA_ByteString_copy(&request->clientNonce,
618
4.66k
                                            &newSession->clientNonce);
619
620
4.66k
#ifdef UA_ENABLE_DIAGNOSTICS
621
4.66k
    rh->serviceResult |= UA_String_copy(&request->serverUri,
622
4.66k
                                        &newSession->diagnostics.serverUri);
623
4.66k
    rh->serviceResult |= UA_String_copy(&request->endpointUrl,
624
4.66k
                                        &newSession->diagnostics.endpointUrl);
625
4.66k
#endif
626
627
4.66k
    if(rh->serviceResult != UA_STATUSCODE_GOOD) {
628
0
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
629
0
                             "CreateSession: Could not create new session (%s)",
630
0
                             UA_StatusCode_name(rh->serviceResult));
631
0
        UA_Session_remove(server, newSession, UA_SHUTDOWNREASON_REJECT);
632
0
        return;
633
0
    }
634
635
    /* Get the SecurityPolicy for UserToken encryption and instantiate it. The
636
     * same selection is done for the local endpoints in
637
     * updateEndpointUserIdentityToken. Don't mix RSA/ECC between channel and
638
     * authentication. */
639
4.66k
    UA_SecurityPolicy *sessionSp = NULL;
640
4.66k
    if(request->clientCertificate.length > 0) {
641
29
        if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE)
642
29
            sessionSp = getDefaultEncryptedSecurityPolicy(server, sp->policyType);
643
0
        else
644
0
            sessionSp = sp;
645
29
    }
646
4.66k
    if(sessionSp) {
647
0
        rh->serviceResult =
648
0
            createCheckSessionAuthSecurityPolicyContext(server, newSession,
649
0
                                                        sessionSp, "CreateSession",
650
0
                                                        request->clientCertificate);
651
0
        if(rh->serviceResult != UA_STATUSCODE_GOOD) {
652
0
            UA_Session_remove(server, newSession, UA_SHUTDOWNREASON_REJECT);
653
0
            return;
654
0
        }
655
0
    }
656
657
    /* Generate the nonce. This uses the session-SecurityPolicy if defined.
658
     * Otherwise the SecurityPolicy of the SecureChannel. */
659
4.66k
    rh->serviceResult = UA_Session_generateNonce(newSession);
660
4.66k
    if(rh->serviceResult != UA_STATUSCODE_GOOD) {
661
0
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
662
0
                             "CreateSession: Could not create the server nonce (%s)",
663
0
                             UA_StatusCode_name(rh->serviceResult));
664
0
        UA_Session_remove(server, newSession, UA_SHUTDOWNREASON_REJECT);
665
0
        return;
666
0
    }
667
668
    /* If an ECC policy, create an ephemeral key to be returned in the response.
669
     * The private part of the ephemeral key is persisted in the
670
     * Session-SecurityPolicy context. Until it gets overridden during
671
     * ActivateSession. */
672
4.66k
    if(sessionSp && UA_SecurityPolicy_isEcc(sessionSp) &&
673
0
       clientRequestedEphemeralKey(&request->requestHeader.additionalHeader)) {
674
0
        rh->serviceResult = addEphemeralKeyAdditionalHeader(server, newSession,
675
0
                                                            &rh->additionalHeader);
676
0
        if(rh->serviceResult != UA_STATUSCODE_GOOD) {
677
0
            UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
678
0
                                 "CreateSession: Could not prepare the ephemeral key (%s)",
679
0
                                 UA_StatusCode_name(rh->serviceResult));
680
0
            UA_Session_remove(server, newSession, UA_SHUTDOWNREASON_REJECT);
681
0
            return;
682
0
        }
683
0
    }
684
685
    /* Prepare the response */
686
4.66k
    response->sessionId = newSession->sessionId;
687
4.66k
    response->revisedSessionTimeout = (UA_Double)newSession->timeout;
688
4.66k
    response->authenticationToken = newSession->authenticationToken;
689
4.66k
    rh->serviceResult |= UA_ByteString_copy(&newSession->serverNonce,
690
4.66k
                                            &response->serverNonce);
691
    /* The CreateSessionResponse carries the Server's application instance
692
     * certificate so the Client can encrypt the UserIdentityToken with it. This
693
     * is needed even on a #None SecureChannel when the user token is encrypted
694
     * "on top" (sessionSp is then the user-token encryption policy, whose
695
     * localCertificate is the Server certificate; the #None channel policy has
696
     * no certificate). So copy it whenever a session-auth SecurityPolicy was
697
     * instantiated, regardless of the channel SecurityMode. */
698
4.66k
    if(sessionSp)
699
0
        rh->serviceResult |= UA_ByteString_copy(&sessionSp->localCertificate,
700
0
                                                &response->serverCertificate);
701
702
    /* Copy the server's endpointdescriptions into the response */
703
4.66k
    rh->serviceResult |= setCurrentEndpointsArray(server, request->endpointUrl,
704
4.66k
                                                  NULL, 0,
705
4.66k
                                                  &response->serverEndpoints,
706
4.66k
                                                  &response->serverEndpointsSize);
707
708
4.66k
    if(rh->serviceResult != UA_STATUSCODE_GOOD) {
709
0
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
710
0
                             "CreateSession: Could not prepare the response (%s)",
711
0
                             UA_StatusCode_name(rh->serviceResult));
712
0
        UA_Session_remove(server, newSession, UA_SHUTDOWNREASON_REJECT);
713
0
        return;
714
0
    }
715
716
    /* Sign the signature */
717
4.66k
    rh->serviceResult |=
718
4.66k
        signCreateSessionResponse(server, channel, request, response);
719
4.66k
    if(rh->serviceResult != UA_STATUSCODE_GOOD) {
720
0
        UA_Session_remove(server, newSession, UA_SHUTDOWNREASON_REJECT);
721
0
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
722
0
                             "CreateSession: Could not sign the response (%s)",
723
0
                             UA_StatusCode_name(rh->serviceResult));
724
0
        return;
725
0
    }
726
727
4.66k
#ifdef UA_ENABLE_DIAGNOSTICS
728
4.66k
    UA_EventLoop *el = server->config.eventLoop;
729
4.66k
    newSession->diagnostics.clientConnectionTime = el->dateTime_now(el);
730
4.66k
    newSession->diagnostics.clientLastContactTime =
731
4.66k
        newSession->diagnostics.clientConnectionTime;
732
733
    /* Create the object in the information model */
734
4.66k
    createSessionObject(server, newSession);
735
4.66k
#endif
736
737
4.66k
    UA_LOG_INFO_SESSION(server->config.logging, newSession, "Session created");
738
4.66k
}
739
740
static UA_StatusCode
741
checkCertificateSignature(const UA_Server *server, const UA_SecurityPolicy *tokenSp,
742
                          void *channelContext, const UA_ByteString *serverNonce,
743
                          const UA_SignatureData *signature,
744
0
                          const bool isUserTokenSignature, bool allowEmptyLocalCert) {
745
0
    UA_assert(tokenSp != NULL);
746
747
    /* Check for zero signature length */
748
0
    if(signature->signature.length == 0) {
749
0
        if(isUserTokenSignature)
750
0
            return UA_STATUSCODE_BADUSERSIGNATUREINVALID;
751
0
        return UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID;
752
0
    }
753
754
    /* Data to verify is calculated by appending the serverNonce to the local
755
     * certificate */
756
0
    const UA_ByteString *localCertificate = &tokenSp->localCertificate;
757
0
    UA_ByteString dataToVerify;
758
0
    size_t dataToVerifySize = localCertificate->length + serverNonce->length;
759
0
    UA_StatusCode res = UA_ByteString_allocBuffer(&dataToVerify, dataToVerifySize);
760
0
    if(res != UA_STATUSCODE_GOOD)
761
0
        return res;
762
763
0
    memcpy(dataToVerify.data, localCertificate->data, localCertificate->length);
764
0
    memcpy(dataToVerify.data + localCertificate->length, serverNonce->data, serverNonce->length);
765
766
0
 check_certificate:
767
0
    res = tokenSp->asymSignatureAlgorithm.
768
0
        verify(tokenSp, channelContext, &dataToVerify, &signature->signature);
769
0
    if(res != UA_STATUSCODE_GOOD) {
770
0
        if(isUserTokenSignature)
771
0
            res = UA_STATUSCODE_BADUSERSIGNATUREINVALID;
772
0
        else
773
0
            res = UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID;
774
0
    }
775
776
0
    if(dataToVerify.data != serverNonce->data)
777
0
        UA_ByteString_clear(&dataToVerify);
778
779
    /* Workaround: If the SecureChannel is #None, the client might have used the
780
     * ApplicationInstanceCertificate of the server (maybe it was in the
781
     * EndpointDescription) or not. If the MessageSecurityMode is #None, then
782
     * retry with an empty server certificate. */
783
0
    if(res != UA_STATUSCODE_GOOD && localCertificate->length > 0 && allowEmptyLocalCert) {
784
0
        localCertificate = &UA_BYTESTRING_NULL;
785
0
        dataToVerify = *serverNonce;
786
0
        goto check_certificate;
787
0
    }
788
789
0
    return res;
790
0
}
791
792
/* Always sets tokenSp (default: SecurityPolicy of the channel) */
793
static const UA_UserTokenPolicy *
794
selectTokenPolicy(UA_Server *server, UA_SecureChannel *channel,
795
                  UA_Session *session, const UA_ExtensionObject *identityToken,
796
                  const UA_EndpointDescription *ed,
797
1.45k
                  UA_SecurityPolicy **tokenSp) {
798
    /* If no UserTokenPolicies are configured in the endpoint, then use
799
     * those configured in the AccessControl plugin. */
800
1.45k
    size_t identPoliciesSize = ed->userIdentityTokensSize;
801
1.45k
    const UA_UserTokenPolicy *identPolicies = ed->userIdentityTokens;
802
1.45k
    if(identPoliciesSize == 0) {
803
1.45k
        identPoliciesSize = server->config.accessControl.userTokenPoliciesSize;
804
1.45k
        identPolicies = server->config.accessControl.userTokenPolicies;
805
1.45k
    }
806
807
    /* Match the UserTokenType */
808
1.45k
    const UA_DataType *tokenDataType = identityToken->content.decoded.type;
809
1.50k
    for(size_t j = 0; j < identPoliciesSize; j++) {
810
1.47k
        const UA_UserTokenPolicy *pol = &identPolicies[j];
811
812
        /* Part 4, Section 5.6.3.2, Table 17: A NULL or empty
813
         * UserIdentityToken should be treated as Anonymous */
814
1.47k
        if(identityToken->encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY &&
815
1.43k
           pol->tokenType == UA_USERTOKENTYPE_ANONYMOUS) {
816
1.43k
            *tokenSp = channel->securityPolicy;
817
1.43k
            return pol;
818
1.43k
        }
819
820
        /* Expect decoded content if not anonymous */
821
46
        if(!tokenDataType)
822
42
            continue;
823
824
        /* Match the DataType of the provided token with the policy */
825
4
        switch(pol->tokenType) {
826
2
        case UA_USERTOKENTYPE_ANONYMOUS:
827
2
            if(tokenDataType != &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN])
828
2
                continue;
829
0
            break;
830
0
        case UA_USERTOKENTYPE_USERNAME:
831
0
            if(tokenDataType != &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN])
832
0
                continue;
833
0
            break;
834
2
        case UA_USERTOKENTYPE_CERTIFICATE:
835
2
            if(tokenDataType != &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN])
836
2
                continue;
837
0
            break;
838
0
        case UA_USERTOKENTYPE_ISSUEDTOKEN:
839
0
            if(tokenDataType != &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN])
840
0
                continue;
841
0
            break;
842
0
        default:
843
0
            continue;
844
4
        }
845
846
        /* All valid token data types start with a string policyId. Casting
847
         * to anonymous hence works for all of them. */
848
0
        UA_AnonymousIdentityToken *token = (UA_AnonymousIdentityToken*)
849
0
            identityToken->content.decoded.data;
850
851
        /* In setCurrentEndpointsArray we prepend the PolicyId with the
852
         * SecurityMode of the endpoint and the postfix of the
853
         * SecurityPolicyUri to make it unique. Check the PolicyId. */
854
0
        if(pol->policyId.length > token->policyId.length)
855
0
            continue;
856
0
        UA_String policyPrefix = token->policyId;
857
0
        policyPrefix.length = pol->policyId.length;
858
0
        if(!UA_String_equal(&policyPrefix, &pol->policyId))
859
0
            continue;
860
861
        /* Get the SecurityPolicy for the endpoint from the postfix */
862
0
        UA_String utPolPostfix = securityPolicyUriPostfix(token->policyId);
863
0
        UA_SecurityPolicy *candidateSp =
864
0
            getSecurityPolicyByPostfix(server, utPolPostfix);
865
0
        if(!candidateSp) {
866
0
            UA_LOG_WARNING_SESSION(server->config.logging, session,
867
0
                                   "ActivateSession: The UserTokenPolicy of "
868
0
                                   "the endpoint defines an unknown "
869
0
                                   "SecurityPolicy %S",
870
0
                                   pol->securityPolicyUri);
871
0
            continue;
872
0
        }
873
874
        /* A non-anonymous authentication token is transmitted over an
875
         * unencrypted SecureChannel */
876
0
        if(pol->tokenType != UA_USERTOKENTYPE_ANONYMOUS &&
877
0
           channel->securityPolicy->policyType == UA_SECURITYPOLICYTYPE_NONE &&
878
0
           candidateSp->policyType == UA_SECURITYPOLICYTYPE_NONE) {
879
            /* Check if the allowNonePolicyPassword option is set.
880
             * But this exception only works for Username/Password. */
881
0
            if(!server->config.allowNonePolicyPassword ||
882
0
               pol->tokenType != UA_USERTOKENTYPE_USERNAME)
883
0
                continue;
884
0
        }
885
886
        /* Found a match policy */
887
0
        *tokenSp = candidateSp;
888
0
        return pol;
889
0
    }
890
891
23
    return NULL;
892
1.45k
}
893
894
static void
895
selectEndpointAndTokenPolicy(UA_Server *server, UA_SecureChannel *channel,
896
                             UA_Session *session,
897
                             const UA_ExtensionObject *identityToken,
898
                             const UA_EndpointDescription **ed,
899
                             const UA_UserTokenPolicy **utp,
900
1.45k
                             UA_SecurityPolicy **tokenSp) {
901
1.45k
    UA_ServerConfig *sc = &server->config;
902
1.47k
    for(size_t i = 0; i < sc->endpointsSize; ++i) {
903
1.45k
        const UA_EndpointDescription *desc = &sc->endpoints[i];
904
905
        /* Match the Security Mode */
906
1.45k
        if(desc->securityMode != channel->securityMode)
907
0
            continue;
908
909
        /* Match the SecurityPolicy of the endpoint with the current channel */
910
1.45k
        if(!UA_String_equal(&desc->securityPolicyUri,
911
1.45k
                            &channel->securityPolicy->policyUri))
912
0
            continue;
913
914
        /* Select the UserTokenPolicy from the Endpoint */
915
1.45k
        *utp = selectTokenPolicy(server, channel, session,
916
1.45k
                                 identityToken, desc, tokenSp);
917
1.45k
        if(*utp) {
918
            /* Match found */
919
1.43k
            *ed = desc;
920
1.43k
            return;
921
1.43k
        }
922
1.45k
    }
923
1.45k
}
924
925
static UA_StatusCode
926
0
hideX509IdentityTokenValidationStatus(UA_StatusCode status) {
927
0
    if(status == UA_STATUSCODE_GOOD)
928
0
        return UA_STATUSCODE_GOOD;
929
0
    return UA_STATUSCODE_BADIDENTITYTOKENREJECTED;
930
0
}
931
932
static UA_StatusCode
933
checkActivateSessionX509(UA_Server *server, UA_SecureChannel *channel, UA_Session *session,
934
                         const UA_SecurityPolicy *tokenSp, UA_X509IdentityToken* token,
935
0
                         const UA_SignatureData *tokenSignature) {
936
    /* The SecurityPolicy must not be None for the signature */
937
0
    if(tokenSp->policyType == UA_SECURITYPOLICYTYPE_NONE)
938
0
        return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
939
940
    /* We need a channel context with the user certificate in order to reuse
941
     * the signature checking code. */
942
0
    void *tempChannelContext;
943
0
    UA_StatusCode res = tokenSp->newChannelContext(tokenSp, &token->certificateData,
944
0
                                                   &tempChannelContext);
945
0
    if(res != UA_STATUSCODE_GOOD) {
946
0
        UA_LOG_ERROR_SESSION(server->config.logging, session,
947
0
                             "ActivateSession: Failed to create a context "
948
0
                             "for the SecurityPolicy %S", tokenSp->policyUri);
949
0
        return res;
950
0
    }
951
952
    /* Check the user token signature. The channel-bound v1.05.07 layout (see
953
     * the cert-role table at UA_SecureChannel_buildUserTokenSignatureData) is
954
     * used only when BOTH the SecureChannel AND the user-token SecurityPolicy
955
     * are enhanced; a legacy RSA / old-ECC user token uses the legacy layout
956
     * even over an enhanced (AesGcm) SecureChannel. */
957
0
    if(UA_SecurityPolicy_isEnhancedSecurity(channel->securityPolicy) &&
958
0
       UA_SecurityPolicy_isEnhancedSecurity(tokenSp)) {
959
0
        if(tokenSignature->signature.length == 0) {
960
0
            res = UA_STATUSCODE_BADUSERSIGNATUREINVALID;
961
0
            goto out;
962
0
        }
963
0
        UA_ByteString dataToVerify = UA_BYTESTRING_NULL;
964
0
        res = UA_SecureChannel_buildUserTokenSignatureData(
965
0
            channel, &session->serverNonce, &session->clientNonce,
966
0
            &channel->securityPolicy->localCertificate,
967
0
            &channel->securityPolicy->localCertificate,
968
0
            &channel->remoteCertificate, &channel->remoteCertificate, &dataToVerify);
969
0
        if(res == UA_STATUSCODE_GOOD) {
970
0
            res = tokenSp->asymSignatureAlgorithm.verify(
971
0
                tokenSp, tempChannelContext, &dataToVerify, &tokenSignature->signature);
972
0
            if(res != UA_STATUSCODE_GOOD)
973
0
                res = UA_STATUSCODE_BADUSERSIGNATUREINVALID;
974
0
        }
975
0
        UA_ByteString_clear(&dataToVerify);
976
0
    } else {
977
0
        res = checkCertificateSignature(server, tokenSp, tempChannelContext, &session->serverNonce,
978
0
                                        tokenSignature, true,
979
0
                                        (channel->securityMode == UA_MESSAGESECURITYMODE_NONE));
980
0
    }
981
0
    if(res != UA_STATUSCODE_GOOD) {
982
0
        UA_LOG_ERROR_SESSION(server->config.logging, session,
983
0
                             "ActivateSession: User token signature check "
984
0
                             "failed with StatusCode %s", UA_StatusCode_name(res));
985
0
        goto out;
986
0
    }
987
988
    /* Validate the certificate against the SessionPKI */
989
0
    res = validateCertificate(server, &server->config.sessionPKI,
990
0
                              session->channel, session, "ActivateSession",
991
0
                              NULL, token->certificateData);
992
0
    res = hideX509IdentityTokenValidationStatus(res);
993
994
0
 out:
995
    /* Delete the temporary channel context */
996
0
    tokenSp->deleteChannelContext(tokenSp, tempChannelContext);
997
0
    return res;
998
0
}
999
1000
static UA_StatusCode
1001
decryptUserToken(UA_Server *server, UA_Session *session, UA_SecureChannel *channel,
1002
                 UA_SecurityPolicy *tokenSp, UA_ByteString *token,
1003
0
                 const UA_String encryptionAlgorithm) {
1004
    /* Not encrypted */
1005
0
    if(tokenSp->policyType == UA_SECURITYPOLICYTYPE_NONE) {
1006
0
        if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE)
1007
0
            UA_LOG_WARNING_SESSION(server->config.logging, session,
1008
0
                                   "ActivateSession: Processing an unencrypted "
1009
0
                                   "UserToken. This is dangerous for the server "
1010
0
                                   "to allow.");
1011
0
        return UA_STATUSCODE_GOOD;
1012
0
    }
1013
1014
    /* Test if the correct encryption algorithm is used. Note that some clients
1015
     * don't set the EncryptionAlgorithmUri. Skip the check for those.*/
1016
0
    if(encryptionAlgorithm.length > 0 &&
1017
0
       !UA_String_equal(&tokenSp->asymEncryptionAlgorithm.uri,
1018
0
                        &encryptionAlgorithm)) {
1019
0
        UA_LOG_ERROR_SESSION(server->config.logging, session,
1020
0
                             "ActivateSession: Encryption algorithm used "
1021
0
                             "for the UserIdentityToken does not match "
1022
0
                             "the endpoint");
1023
0
        return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
1024
0
    }
1025
1026
    /* Try to create an instance of the authentication SecurityPolicy to decrypt
1027
     * the UserIdentityToken. For RSA-based async encryption we don't need that. */
1028
0
    UA_ByteString applicationCert = (channel->remoteCertificate.length > 0) ?
1029
0
        channel->remoteCertificate : session->clientCertificate;
1030
0
    UA_StatusCode res =
1031
0
        createCheckSessionAuthSecurityPolicyContext(server, session, tokenSp,
1032
0
                                                    "ActivateSession", applicationCert);
1033
0
    if(res != UA_STATUSCODE_GOOD)
1034
0
        return res;
1035
1036
    /* Decrypt the token. Differentiate between secret encryptions (ECC,
1037
     * legacy).
1038
     * TODO: Implement "modern" RSA secret encryption */
1039
0
    if(UA_SecurityPolicy_isEcc(tokenSp)) {
1040
0
        res = decryptUserTokenEcc(server->config.logging, channel,
1041
0
                                session->sessionSp, session->sessionSpContext,
1042
0
                                session->serverNonce, token);
1043
0
    } else {
1044
0
        res = decryptSecretLegacy(session->sessionSp, session->sessionSpContext,
1045
0
                                  session->serverNonce, token);
1046
0
    }
1047
0
    if(res != UA_STATUSCODE_GOOD) {
1048
0
        UA_LOG_ERROR_SESSION(server->config.logging, session,
1049
0
                             "ActivateSession: Could not decrypt/"
1050
0
                             "cryptographically validate the UserIdentityToken "
1051
0
                             "with the StatusCode %s", UA_StatusCode_name(res));
1052
0
    }
1053
0
    return res;
1054
0
}
1055
1056
static UA_StatusCode
1057
getClientUserId(const UA_ExtensionObject *userIdentityToken,
1058
2.80k
                UA_UserTokenType tokenType, UA_String *clientUserId) {
1059
2.80k
    UA_String_init(clientUserId);
1060
2.80k
    if(tokenType == UA_USERTOKENTYPE_ANONYMOUS)
1061
2.80k
        return UA_STATUSCODE_GOOD;
1062
1063
0
    if(userIdentityToken->encoding < UA_EXTENSIONOBJECT_DECODED)
1064
0
        return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
1065
1066
0
    if(tokenType == UA_USERTOKENTYPE_USERNAME) {
1067
0
        const UA_UserNameIdentityToken *userToken = (const UA_UserNameIdentityToken *)
1068
0
            userIdentityToken->content.decoded.data;
1069
0
        return UA_String_copy(&userToken->userName, clientUserId);
1070
0
    }
1071
1072
0
    if(tokenType == UA_USERTOKENTYPE_CERTIFICATE) {
1073
0
        UA_X509IdentityToken *userCertToken = (UA_X509IdentityToken *)
1074
0
            userIdentityToken->content.decoded.data;
1075
0
        return UA_CertificateUtils_getSubjectName(&userCertToken->certificateData,
1076
0
                                                   clientUserId);
1077
0
    }
1078
1079
    /* There is no generic way to derive the ClientUserId from an issued
1080
     * token. Keep the identifier empty and distinguish it from anonymous via
1081
     * the token type. */
1082
0
    return UA_STATUSCODE_GOOD;
1083
0
}
1084
1085
/* TODO: Check all of the following: The Server shall verify that the
1086
 * Certificate the Client used to create the new SecureChannel is the same as
1087
 * the Certificate used to create the original SecureChannel. In addition, the
1088
 * Server shall verify that the Client supplied a UserIdentityToken that is
1089
 * identical to the token currently associated with the Session. Once the Server
1090
 * accepts the new SecureChannel it shall reject requests sent via the old
1091
 * SecureChannel. */
1092
1093
#define UA_SESSION_REJECT                                               \
1094
157
    do {                                                                \
1095
157
        UA_String_clear(&clientUserId);                                  \
1096
157
        UA_ByteString_clear(&userCertificate);                           \
1097
157
        server->serverDiagnosticsSummary.rejectedSessionCount++;        \
1098
157
        return;                                                         \
1099
157
    } while(0)
1100
1101
#define UA_SECURITY_REJECT                                              \
1102
0
    do {                                                                \
1103
0
        UA_String_clear(&clientUserId);                                  \
1104
0
        UA_ByteString_clear(&userCertificate);                           \
1105
0
        server->serverDiagnosticsSummary.securityRejectedSessionCount++; \
1106
0
        server->serverDiagnosticsSummary.rejectedSessionCount++;        \
1107
0
        return;                                                         \
1108
0
    } while(0)
1109
1110
void
1111
Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
1112
                        const UA_ActivateSessionRequest *req,
1113
1.58k
                        UA_ActivateSessionResponse *resp) {
1114
1.58k
    UA_LOCK_ASSERT(&server->serviceMutex);
1115
1.58k
    UA_ResponseHeader *rh = &resp->responseHeader;
1116
1.58k
    UA_String clientUserId = UA_STRING_NULL;
1117
1.58k
    UA_ByteString userCertificate = UA_BYTESTRING_NULL;
1118
1119
    /* Get the session */
1120
1.58k
    UA_Session *session =
1121
1.58k
        getSessionByToken(server, &req->requestHeader.authenticationToken);
1122
1.58k
    if(!session) {
1123
134
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
1124
134
                             "ActivateSession: Session not found");
1125
134
        rh->serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
1126
134
        UA_SESSION_REJECT;
1127
134
    }
1128
1129
    /* Part 4, §5.6.3: When the ActivateSession Service is called for the
1130
     * first time then the Server shall reject the request if the
1131
     * SecureChannel is not same as the one associated with the
1132
     * CreateSession request. Subsequent calls to ActivateSession may be
1133
     * associated with different SecureChannels. */
1134
1.45k
    if(!session->activated && session->channel != channel) {
1135
0
        UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
1136
0
                             "ActivateSession: The Session has to be initially "
1137
0
                             "activated on the SecureChannel that created it");
1138
0
        rh->serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
1139
0
        UA_SESSION_REJECT;
1140
0
    }
1141
1142
    /* Has the session timed out? */
1143
1.45k
    UA_EventLoop *el = server->config.eventLoop;
1144
1.45k
    UA_DateTime nowMonotonic = el->dateTime_nowMonotonic(el);
1145
1.45k
    if(session->validTill < nowMonotonic) {
1146
0
        UA_LOG_ERROR_SESSION(server->config.logging, session,
1147
0
                             "ActivateSession: The Session has timed out");
1148
0
        rh->serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
1149
0
        UA_SESSION_REJECT;
1150
0
    }
1151
1152
    /* Check the client signature */
1153
1.45k
    if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
1154
1.45k
       channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
1155
0
        const UA_SecurityPolicy *csp = channel->securityPolicy;
1156
0
        if(UA_SecurityPolicy_isEnhancedSecurity(csp)) {
1157
            /* Channel-bound v1.05.07 ClientSignature (see the cert-role table at
1158
             * UA_SecureChannel_buildActivateSessionSignatureData). clientNonce is
1159
             * the ClientNonce stored at CreateSession. */
1160
0
            if(req->clientSignature.signature.length == 0) {
1161
0
                rh->serviceResult = UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID;
1162
0
            } else {
1163
0
                UA_ByteString dataToVerify = UA_BYTESTRING_NULL;
1164
0
                rh->serviceResult = UA_SecureChannel_buildActivateSessionSignatureData(
1165
0
                    channel, &session->serverNonce, &session->clientNonce,
1166
0
                    &csp->localCertificate, &csp->localCertificate,
1167
0
                    &channel->remoteCertificate, &dataToVerify);
1168
0
                if(rh->serviceResult == UA_STATUSCODE_GOOD) {
1169
0
                    rh->serviceResult = csp->asymSignatureAlgorithm.verify(
1170
0
                        csp, channel->channelContext, &dataToVerify,
1171
0
                        &req->clientSignature.signature);
1172
0
                    if(rh->serviceResult != UA_STATUSCODE_GOOD)
1173
0
                        rh->serviceResult = UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID;
1174
0
                }
1175
0
                UA_ByteString_clear(&dataToVerify);
1176
0
            }
1177
0
        } else {
1178
0
            rh->serviceResult =
1179
0
                checkCertificateSignature(server, channel->securityPolicy,
1180
0
                                          channel->channelContext, &session->serverNonce,
1181
0
                                          &req->clientSignature, false, false);
1182
0
        }
1183
0
        if(rh->serviceResult != UA_STATUSCODE_GOOD) {
1184
0
            UA_LOG_ERROR_SESSION(server->config.logging, session,
1185
0
                                 "ActivateSession: Client signature check failed "
1186
0
                                 "with StatusCode %s",
1187
0
                                 UA_StatusCode_name(rh->serviceResult));
1188
0
            UA_SECURITY_REJECT;
1189
0
        }
1190
0
    }
1191
1192
    /* Find the matching Endpoint with UserTokenPolicy.
1193
     * Also sets the SecurityPolicy used to encrypt the token. */
1194
1.45k
    const UA_EndpointDescription *ed = NULL;
1195
1.45k
    const UA_UserTokenPolicy *utp = NULL;
1196
1.45k
    UA_SecurityPolicy *tokenSp = NULL;
1197
1.45k
    selectEndpointAndTokenPolicy(server, channel, session,
1198
1.45k
                                 &req->userIdentityToken,
1199
1.45k
                                 &ed, &utp, &tokenSp);
1200
1.45k
    if(!ed || !tokenSp) {
1201
23
        UA_LOG_ERROR_SESSION(server->config.logging, session,
1202
23
                             "ActivateSession: Requested Endpoint/UserTokenPolicy "
1203
23
                             "not available");
1204
23
        rh->serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
1205
23
        UA_SESSION_REJECT;
1206
23
    }
1207
1208
    /* Decrypt (or validate the signature) of the UserToken. The DataType of the
1209
     * UserToken was already checked in selectEndpointAndTokenPolicy. This
1210
     * replaces the content of the token in-situ. */
1211
1.43k
    switch(utp->tokenType) {
1212
1.43k
    case UA_USERTOKENTYPE_ANONYMOUS:
1213
1.43k
        break;
1214
0
    case UA_USERTOKENTYPE_USERNAME: {
1215
0
        UA_UserNameIdentityToken *token = (UA_UserNameIdentityToken *)
1216
0
           req->userIdentityToken.content.decoded.data;
1217
0
        rh->serviceResult =
1218
0
            decryptUserToken(server, session, channel, tokenSp,
1219
0
                             &token->password, token->encryptionAlgorithm);
1220
0
        break; }
1221
0
    case UA_USERTOKENTYPE_CERTIFICATE: {
1222
        /* Check the signature and verify the certificate in the sessionPKI */
1223
0
        UA_X509IdentityToken* x509token = (UA_X509IdentityToken*)
1224
0
            req->userIdentityToken.content.decoded.data;
1225
0
        rh->serviceResult =
1226
0
            checkActivateSessionX509(server, channel, session, tokenSp, x509token,
1227
0
                                     &req->userTokenSignature);
1228
0
        break; }
1229
0
    case UA_USERTOKENTYPE_ISSUEDTOKEN: {
1230
0
        UA_IssuedIdentityToken *token = (UA_IssuedIdentityToken*)
1231
0
            req->userIdentityToken.content.decoded.data;
1232
0
        rh->serviceResult =
1233
0
            decryptUserToken(server, session, channel, tokenSp,
1234
0
                             &token->tokenData, token->encryptionAlgorithm);
1235
0
        break; }
1236
0
    default:
1237
0
        rh->serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
1238
0
        break;
1239
1.43k
    }
1240
1241
    /* Could not decrypt the UserIdentityToken */
1242
1.43k
    if(rh->serviceResult != UA_STATUSCODE_GOOD)
1243
0
        UA_SECURITY_REJECT;
1244
1245
    /* Do not let access control replace the user identity of an already
1246
     * activated Session. Re-activation with the same identity remains
1247
     * supported. */
1248
1.43k
    rh->serviceResult =
1249
1.43k
        getClientUserId(&req->userIdentityToken, utp->tokenType, &clientUserId);
1250
1.43k
    if(rh->serviceResult != UA_STATUSCODE_GOOD)
1251
0
        UA_SECURITY_REJECT;
1252
    /* Subject names need not uniquely identify certificates. Keep the full
1253
     * certificate for comparison while preserving the diagnostic user name. */
1254
1.43k
    if(utp->tokenType == UA_USERTOKENTYPE_CERTIFICATE) {
1255
0
        const UA_X509IdentityToken *token = (const UA_X509IdentityToken*)
1256
0
            req->userIdentityToken.content.decoded.data;
1257
0
        rh->serviceResult =
1258
0
            UA_ByteString_copy(&token->certificateData, &userCertificate);
1259
0
        if(rh->serviceResult != UA_STATUSCODE_GOOD)
1260
0
            UA_SECURITY_REJECT;
1261
0
    }
1262
1263
1.43k
    if(session->activated &&
1264
418
       (utp->tokenType != session->userTokenType ||
1265
418
        !UA_String_equal(&clientUserId, &session->clientUserIdOfSession) ||
1266
418
        !UA_ByteString_equal(&userCertificate, &session->userCertificate))) {
1267
0
        rh->serviceResult =
1268
0
            UA_STATUSCODE_BADIDENTITYCHANGENOTSUPPORTED;
1269
0
        UA_SECURITY_REJECT;
1270
0
    }
1271
1272
    /* Callback into the access control plugin.
1273
     * This will attach a custom context pointer to the session. */
1274
1.43k
    rh->serviceResult = server->config.accessControl.
1275
1.43k
        activateSession(server, &server->config.accessControl, ed,
1276
1.43k
                        &channel->remoteCertificate, &session->sessionId,
1277
1.43k
                        &req->userIdentityToken, &session->context);
1278
1.43k
    if(rh->serviceResult != UA_STATUSCODE_GOOD) {
1279
0
        UA_LOG_ERROR_SESSION(server->config.logging, session,
1280
0
                             "ActivateSession: The AccessControl plugin "
1281
0
                             "denied the activation with the StatusCode %s",
1282
0
                             UA_StatusCode_name(rh->serviceResult));
1283
0
        UA_SECURITY_REJECT;
1284
0
    }
1285
1286
    /* Attach the session to the currently used channel if the session isn't
1287
     * attached to a channel or if the session is activated on a different
1288
     * channel than it is attached to. */
1289
1.43k
    if(!session->channel || session->channel != channel) {
1290
        /* Attach the new SecureChannel, the old channel will be detached if present */
1291
0
        UA_Session_attachToSecureChannel(server, session, channel);
1292
0
        UA_LOG_INFO_SESSION(server->config.logging, session,
1293
0
                            "ActivateSession: Session attached to new channel");
1294
0
    }
1295
1296
    /* Generate a new session nonce for the next time ActivateSession is called */
1297
1.43k
    rh->serviceResult = UA_Session_generateNonce(session);
1298
1.43k
    rh->serviceResult |= UA_ByteString_copy(&session->serverNonce,
1299
1.43k
                                            &resp->serverNonce);
1300
1.43k
    if(rh->serviceResult != UA_STATUSCODE_GOOD) {
1301
0
        UA_Session_detachFromSecureChannel(server, session);
1302
0
        UA_LOG_ERROR_SESSION(server->config.logging, session,
1303
0
                             "ActivateSession: Could not generate the server nonce");
1304
0
        UA_SESSION_REJECT;
1305
0
    }
1306
1307
    /* Set the Locale */
1308
1.43k
    if(req->localeIdsSize > 0) {
1309
        /* Part 4, §5.6.3.2: This parameter only needs to be specified during
1310
         * the first call to ActivateSession during a single application
1311
         * Session. If it is not specified the Server shall keep using the
1312
         * current localeIds for the Session. */
1313
61
        UA_String *tmpLocaleIds;
1314
61
        rh->serviceResult |=
1315
61
            UA_Array_copy(req->localeIds, req->localeIdsSize,
1316
61
                          (void**)&tmpLocaleIds, &UA_TYPES[UA_TYPES_STRING]);
1317
61
        if(rh->serviceResult != UA_STATUSCODE_GOOD) {
1318
0
            UA_Session_detachFromSecureChannel(server, session);
1319
0
            UA_LOG_ERROR_SESSION(server->config.logging, session,
1320
0
                                 "ActivateSession: Could not store the "
1321
0
                                 "Session LocaleIds");
1322
0
            UA_SESSION_REJECT;
1323
0
        }
1324
61
        UA_Array_delete(session->localeIds, session->localeIdsSize,
1325
61
                        &UA_TYPES[UA_TYPES_STRING]);
1326
61
        session->localeIds = tmpLocaleIds;
1327
61
        session->localeIdsSize = req->localeIdsSize;
1328
61
    }
1329
1330
    /* Update the Session lifetime */
1331
1.43k
    UA_DateTime now = el->dateTime_now(el);
1332
1.43k
    nowMonotonic = el->dateTime_nowMonotonic(el);
1333
1.43k
    UA_Session_updateLifetime(session, now, nowMonotonic);
1334
1335
    /* If ECC policy, create the new ephemeral key to be returned in the
1336
     * ActivateSession response */
1337
1.43k
    const UA_SecurityPolicy *sessionSp = session->sessionSp;
1338
1.43k
    if(sessionSp && session->sessionSpContext &&
1339
0
       UA_SecurityPolicy_isEcc(sessionSp) &&
1340
0
       clientRequestedEphemeralKey(&req->requestHeader.additionalHeader)) {
1341
0
        rh->serviceResult = addEphemeralKeyAdditionalHeader(server, session,
1342
0
                                                            &rh->additionalHeader);
1343
0
        if(rh->serviceResult != UA_STATUSCODE_GOOD) {
1344
0
            UA_LOG_ERROR_SESSION(server->config.logging, session,
1345
0
                                 "ActivateSession: Could not prepare the "
1346
0
                                 "ephemeral key (%s)",
1347
0
                                 UA_StatusCode_name(rh->serviceResult));
1348
0
            UA_SECURITY_REJECT;
1349
0
        }
1350
0
    }
1351
1352
    /* Activate the session */
1353
1.43k
    UA_Boolean firstActivation = !session->activated;
1354
1.43k
    if(firstActivation) {
1355
1.01k
        session->activated = true;
1356
1.01k
        server->activeSessionCount++;
1357
1.01k
        server->serverDiagnosticsSummary.cumulatedSessionCount++;
1358
1.01k
    }
1359
1360
    /* Store the authenticated ClientUserId. */
1361
1.43k
    UA_String_clear(&session->clientUserIdOfSession);
1362
1.43k
    session->clientUserIdOfSession = clientUserId;
1363
1.43k
    UA_String_init(&clientUserId);
1364
1.43k
    session->userTokenType = utp->tokenType;
1365
1.43k
    UA_ByteString_clear(&session->userCertificate);
1366
1.43k
    session->userCertificate = userCertificate;
1367
1.43k
    UA_ByteString_init(&userCertificate);
1368
1369
1.43k
#ifdef UA_ENABLE_DIAGNOSTICS
1370
    /* Identity changes are rejected for active Sessions. Record the initial
1371
     * authenticated identity once instead of growing the history on every
1372
     * reactivation. */
1373
1.43k
    UA_SessionSecurityDiagnosticsDataType *ssd = &session->securityDiagnostics;
1374
1.43k
    if(firstActivation) {
1375
1.01k
        UA_StatusCode res =
1376
1.01k
            UA_Array_appendCopy((void**)&ssd->clientUserIdHistory,
1377
1.01k
                                &ssd->clientUserIdHistorySize,
1378
1.01k
                                &session->clientUserIdOfSession,
1379
1.01k
                                &UA_TYPES[UA_TYPES_STRING]);
1380
1.01k
        (void)res;
1381
1.01k
    }
1382
1383
    /* Store the auth mechanism */
1384
1.43k
    UA_String_clear(&ssd->authenticationMechanism);
1385
1.43k
    switch(utp->tokenType) {
1386
1.43k
    case UA_USERTOKENTYPE_ANONYMOUS:
1387
1.43k
        ssd->authenticationMechanism = UA_STRING_ALLOC("Anonymous"); break;
1388
0
    case UA_USERTOKENTYPE_USERNAME:
1389
0
        ssd->authenticationMechanism = UA_STRING_ALLOC("UserName"); break;
1390
0
    case UA_USERTOKENTYPE_CERTIFICATE:
1391
0
        ssd->authenticationMechanism = UA_STRING_ALLOC("Certificate"); break;
1392
0
    case UA_USERTOKENTYPE_ISSUEDTOKEN:
1393
0
        ssd->authenticationMechanism = UA_STRING_ALLOC("IssuedToken"); break;
1394
0
    default: break;
1395
1.43k
    }
1396
1.43k
#endif
1397
1398
    /* Notify the application */
1399
1.43k
    notifySession(server, session, UA_APPLICATIONNOTIFICATIONTYPE_SESSION_ACTIVATED);
1400
1401
    /* Log the user for which the Session was activated */
1402
1.43k
    UA_LOG_INFO_SESSION(server->config.logging, session,
1403
1.43k
                        "ActivateSession: Session activated with ClientUserId \"%S\"",
1404
1.43k
                        session->clientUserIdOfSession);
1405
1.43k
}
1406
1407
void
1408
Service_CloseSession(UA_Server *server, UA_SecureChannel *channel,
1409
                     const UA_CloseSessionRequest *request,
1410
160
                     UA_CloseSessionResponse *response) {
1411
160
    UA_LOCK_ASSERT(&server->serviceMutex);
1412
160
    UA_ResponseHeader *rh = &response->responseHeader;
1413
1414
    /* Part 4, 5.6.4: When the CloseSession Service is called before the Session
1415
     * is successfully activated, the Server shall reject the request if the
1416
     * SecureChannel is not the same as the one associated with the
1417
     * CreateSession request.
1418
     *
1419
     * A non-activated Session is already bound to the SecureChannel that
1420
     * created the Session. */
1421
160
    UA_Session *session = NULL;
1422
160
    const UA_NodeId *authToken = &request->requestHeader.authenticationToken;
1423
160
    rh->serviceResult = getBoundSession(server, channel, authToken, &session);
1424
160
    if(!session && rh->serviceResult == UA_STATUSCODE_GOOD)
1425
0
        rh->serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
1426
160
    if(rh->serviceResult != UA_STATUSCODE_GOOD) {
1427
3
        UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
1428
3
                               "CloseSession: No Session activated to the SecureChannel");
1429
3
        return;
1430
3
    }
1431
1432
157
    UA_assert(session); /* Assured by the previous section */
1433
157
    UA_LOG_INFO_SESSION(server->config.logging, session, "Closing the Session");
1434
1435
157
#ifdef UA_ENABLE_SUBSCRIPTIONS
1436
    /* If Subscriptions are not deleted, detach them from the Session */
1437
157
    if(!request->deleteSubscriptions) {
1438
116
        UA_Subscription *sub, *sub_tmp;
1439
116
        TAILQ_FOREACH_SAFE(sub, &session->subscriptions, sessionListEntry, sub_tmp) {
1440
0
            UA_LOG_INFO_SUBSCRIPTION(server->config.logging, sub,
1441
0
                                     "Detaching the Subscription from the Session");
1442
0
            UA_Session_detachSubscription(server, session, sub, true);
1443
0
        }
1444
116
    }
1445
157
#endif
1446
1447
    /* Remove the sesison */
1448
157
    UA_Session_remove(server, session, UA_SHUTDOWNREASON_CLOSE);
1449
157
}
1450
1451
UA_Boolean
1452
Service_Cancel(UA_Server *server, UA_Session *session,
1453
4
               const UA_CancelRequest *request, UA_CancelResponse *response) {
1454
    /* If multithreading is disabled, then there are no async services. If all
1455
     * services are answered "right away", then there are no services that can
1456
     * be cancelled. */
1457
4
    response->cancelCount = UA_AsyncManager_cancel(server, session,
1458
4
                                                   request->requestHandle);
1459
1460
    /* Publish requests for Subscriptions are stored separately */
1461
4
#ifdef UA_ENABLE_SUBSCRIPTIONS
1462
4
    UA_PublishResponseEntry *pre, *pre_tmp;
1463
4
    UA_PublishResponseEntry *prev = NULL;
1464
4
    SIMPLEQ_FOREACH_SAFE(pre, &session->responseQueue, listEntry, pre_tmp) {
1465
        /* Skip entry and set as the previous entry that is kept in the list */
1466
0
        if(pre->response.responseHeader.requestHandle != request->requestHandle) {
1467
0
            prev = pre;
1468
0
            continue;
1469
0
        }
1470
1471
        /* Dequeue */
1472
0
        if(prev)
1473
0
            SIMPLEQ_REMOVE_AFTER(&session->responseQueue, prev, listEntry);
1474
0
        else
1475
0
            SIMPLEQ_REMOVE_HEAD(&session->responseQueue, listEntry);
1476
0
        session->responseQueueSize--;
1477
1478
        /* Cancel the queued Publish response. Keep the CancelResponse good
1479
         * so the client receives the number of cancelled requests. */
1480
0
        pre->response.responseHeader.serviceResult =
1481
0
            UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT;
1482
0
        sendResponse(server, session->channel, pre->requestId,
1483
0
                     (UA_Response *)&pre->response,
1484
0
                     &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]);
1485
0
        UA_PublishResponse_clear(&pre->response);
1486
0
        UA_free(pre);
1487
1488
        /* Increase the CancelCount */
1489
0
        response->cancelCount++;
1490
0
    }
1491
4
#endif
1492
1493
    return true;
1494
4
}