1use std::sync::atomic::{AtomicU16, AtomicU8, Ordering};
8use std::sync::Arc;
9
10use arc_swap::ArcSwap;
11use opcua_nodes::DefaultTypeTree;
12use tracing::{debug, error, warn};
13
14use crate::authenticator::{user_pass_security_policy_id, Password};
15use crate::diagnostics::{ServerDiagnostics, ServerDiagnosticsSummary};
16use crate::node_manager::TypeTreeForUser;
17use opcua_core::comms::url::{hostname_from_url, url_matches_except_host};
18use opcua_core::handle::AtomicHandle;
19use opcua_core::sync::RwLock;
20use opcua_crypto::{user_identity, PrivateKey, SecurityPolicy, X509};
21use opcua_types::{
22 profiles, status_code::StatusCode, ActivateSessionRequest, AnonymousIdentityToken,
23 ApplicationDescription, ApplicationType, EndpointDescription, RegisteredServer,
24 ServerState as ServerStateType, SignatureData, UserNameIdentityToken, UserTokenType,
25 X509IdentityToken,
26};
27use opcua_types::{
28 ByteString, ContextOwned, DateTime, DecodingOptions, Error, ExtensionObject,
29 IssuedIdentityToken, LocalizedText, MessageSecurityMode, NamespaceMap, TypeLoader,
30 TypeLoaderCollection, UAString,
31};
32
33use crate::config::{ServerConfig, ServerEndpoint};
34
35use super::authenticator::{AuthManager, UserToken};
36use super::identity_token::{IdentityToken, POLICY_ID_ANONYMOUS, POLICY_ID_X509};
37use super::{OperationalLimits, ServerCapabilities, ANONYMOUS_USER_TOKEN_ID};
38
39pub struct ServerInfo {
42 pub application_uri: UAString,
44 pub product_uri: UAString,
46 pub application_name: LocalizedText,
48 pub start_time: ArcSwap<DateTime>,
50 pub servers: Vec<String>,
52 pub config: Arc<ServerConfig>,
54 pub server_certificate: Option<X509>,
56 pub server_pkey: Option<PrivateKey>,
58 pub(crate) operational_limits: OperationalLimits,
60 pub state: ArcSwap<ServerStateType>,
62 pub send_buffer_size: usize,
68 pub receive_buffer_size: usize,
70 pub authenticator: Arc<dyn AuthManager>,
72 pub type_tree: Arc<RwLock<DefaultTypeTree>>,
74 pub type_tree_getter: Arc<dyn TypeTreeForUser>,
76 pub subscription_id_handle: AtomicHandle,
78 pub monitored_item_id_handle: AtomicHandle,
80 pub secure_channel_id_handle: Arc<AtomicHandle>,
82 pub capabilities: ServerCapabilities,
84 pub service_level: Arc<AtomicU8>,
86 pub port: AtomicU16,
88 pub type_loaders: RwLock<TypeLoaderCollection>,
90 pub diagnostics: ServerDiagnostics,
92}
93
94impl ServerInfo {
95 pub fn endpoints(
97 &self,
98 endpoint_url: &UAString,
99 transport_profile_uris: &Option<Vec<UAString>>,
100 ) -> Option<Vec<EndpointDescription>> {
101 debug!(
103 "Endpoints requested, transport profile uris {:?}",
104 transport_profile_uris
105 );
106 if let Some(ref transport_profile_uris) = *transport_profile_uris {
107 if !transport_profile_uris.is_empty() {
109 let found_binary_transport = transport_profile_uris.iter().any(|profile_uri| {
111 profile_uri.as_ref() == profiles::TRANSPORT_PROFILE_URI_BINARY
112 });
113 if !found_binary_transport {
114 error!(
115 "Client wants to connect with a non binary transport {:#?}",
116 transport_profile_uris
117 );
118 return None;
119 }
120 }
121 }
122
123 if let Ok(hostname) = hostname_from_url(endpoint_url.as_ref()) {
124 if !hostname.eq_ignore_ascii_case(&self.config.tcp_config.host) {
125 debug!("Endpoint url \"{}\" hostname supplied by caller does not match server's hostname \"{}\"", endpoint_url, &self.config.tcp_config.host);
126 }
127 let endpoints = self
128 .config
129 .endpoints
130 .values()
131 .map(|e| self.new_endpoint_description(e, true))
132 .collect();
133 Some(endpoints)
134 } else {
135 warn!(
136 "Endpoint url \"{}\" is unrecognized, using default",
137 endpoint_url
138 );
139 if let Some(e) = self.config.default_endpoint() {
140 Some(vec![self.new_endpoint_description(e, true)])
141 } else {
142 Some(vec![])
143 }
144 }
145 }
146
147 pub fn endpoint_exists(
150 &self,
151 endpoint_url: &str,
152 security_policy: SecurityPolicy,
153 security_mode: MessageSecurityMode,
154 ) -> bool {
155 self.config
156 .find_endpoint(
157 endpoint_url,
158 &self.base_endpoint(),
159 security_policy,
160 security_mode,
161 )
162 .is_some()
163 }
164
165 pub fn new_endpoint_descriptions(
169 &self,
170 endpoint_url: &str,
171 ) -> Option<Vec<EndpointDescription>> {
172 debug!("find_endpoint, url = {}", endpoint_url);
173 let base_endpoint_url = self.base_endpoint();
174 let endpoints: Vec<EndpointDescription> = self
175 .config
176 .endpoints
177 .iter()
178 .filter(|&(_, e)| {
179 url_matches_except_host(&e.endpoint_url(&base_endpoint_url), endpoint_url)
181 })
182 .map(|(_, e)| self.new_endpoint_description(e, false))
183 .collect();
184 if endpoints.is_empty() {
185 None
186 } else {
187 Some(endpoints)
188 }
189 }
190
191 fn new_endpoint_description(
193 &self,
194 endpoint: &ServerEndpoint,
195 all_fields: bool,
196 ) -> EndpointDescription {
197 let base_endpoint_url = self.base_endpoint();
198
199 let user_identity_tokens = self.authenticator.user_token_policies(endpoint);
200
201 let (server, server_certificate) = if all_fields {
205 (
206 ApplicationDescription {
207 application_uri: self.application_uri.clone(),
208 product_uri: self.product_uri.clone(),
209 application_name: self.application_name.clone(),
210 application_type: self.application_type(),
211 gateway_server_uri: self.gateway_server_uri(),
212 discovery_profile_uri: UAString::null(),
213 discovery_urls: self.discovery_urls(),
214 },
215 self.server_certificate_as_byte_string(),
216 )
217 } else {
218 (
219 ApplicationDescription {
220 application_uri: self.application_uri.clone(),
221 product_uri: UAString::null(),
222 application_name: LocalizedText::null(),
223 application_type: self.application_type(),
224 gateway_server_uri: self.gateway_server_uri(),
225 discovery_profile_uri: UAString::null(),
226 discovery_urls: self.discovery_urls(),
227 },
228 ByteString::null(),
229 )
230 };
231
232 EndpointDescription {
233 endpoint_url: endpoint.endpoint_url(&base_endpoint_url).into(),
234 server,
235 server_certificate,
236 security_mode: endpoint.message_security_mode(),
237 security_policy_uri: UAString::from(endpoint.security_policy().to_uri()),
238 user_identity_tokens: Some(user_identity_tokens),
239 transport_profile_uri: UAString::from(profiles::TRANSPORT_PROFILE_URI_BINARY),
240 security_level: endpoint.security_level,
241 }
242 }
243
244 pub fn discovery_urls(&self) -> Option<Vec<UAString>> {
246 if self.config.discovery_urls.is_empty() {
247 None
248 } else {
249 Some(
250 self.config
251 .discovery_urls
252 .iter()
253 .map(UAString::from)
254 .collect(),
255 )
256 }
257 }
258
259 pub fn application_type(&self) -> ApplicationType {
261 ApplicationType::Server
262 }
263
264 pub fn gateway_server_uri(&self) -> UAString {
266 UAString::null()
267 }
268
269 pub fn state(&self) -> ServerStateType {
271 **self.state.load()
272 }
273
274 pub fn is_running(&self) -> bool {
276 self.state() == ServerStateType::Running
277 }
278
279 pub fn base_endpoint(&self) -> String {
281 format!(
282 "opc.tcp://{}:{}",
283 self.config.tcp_config.host,
284 self.port.load(Ordering::Relaxed)
285 )
286 }
287
288 pub fn server_certificate_as_byte_string(&self) -> ByteString {
290 if let Some(ref server_certificate) = self.server_certificate {
291 server_certificate.as_byte_string()
292 } else {
293 ByteString::null()
294 }
295 }
296
297 pub fn registered_server(&self) -> RegisteredServer {
299 let server_uri = self.application_uri.clone();
300 let product_uri = self.product_uri.clone();
301 let gateway_server_uri = self.gateway_server_uri();
302 let discovery_urls = self.discovery_urls();
303 let server_type = self.application_type();
304 let is_online = self.is_running();
305 let server_names = Some(vec![self.application_name.clone()]);
306 RegisteredServer {
308 server_uri,
309 product_uri,
310 server_names,
311 server_type,
312 gateway_server_uri,
313 discovery_urls,
314 semaphore_file_path: UAString::null(),
315 is_online,
316 }
317 }
318
319 pub async fn authenticate_endpoint(
326 &self,
327 request: &ActivateSessionRequest,
328 endpoint_url: &str,
329 security_policy: SecurityPolicy,
330 security_mode: MessageSecurityMode,
331 user_identity_token: ExtensionObject,
332 server_nonce: &ByteString,
333 ) -> Result<UserToken, Error> {
334 if let Some(endpoint) = self.config.find_endpoint(
336 endpoint_url,
337 &self.base_endpoint(),
338 security_policy,
339 security_mode,
340 ) {
341 match IdentityToken::new(user_identity_token) {
343 IdentityToken::None => {
344 error!("User identity token type unsupported");
345 Err(Error::new(
346 StatusCode::BadIdentityTokenInvalid,
347 "User identity token type unsupported",
348 ))
349 }
350 IdentityToken::Anonymous(token) => {
351 self.authenticate_anonymous_token(endpoint, &token).await
352 }
353 IdentityToken::UserName(token) => {
354 self.authenticate_username_identity_token(
355 endpoint,
356 &token,
357 &self.server_pkey,
358 server_nonce,
359 )
360 .await
361 }
362 IdentityToken::X509(token) => {
363 self.authenticate_x509_identity_token(
364 endpoint,
365 &token,
366 &request.user_token_signature,
367 &self.server_certificate,
368 server_nonce,
369 )
370 .await
371 }
372 IdentityToken::IssuedToken(token) => {
373 self.authenticate_issued_identity_token(
374 endpoint,
375 &token,
376 &self.server_pkey,
377 server_nonce,
378 )
379 .await
380 }
381 IdentityToken::Invalid(o) => Err(Error::new(
382 StatusCode::BadIdentityTokenInvalid,
383 format!(
384 "User identity token type {} is unsupported",
385 o.body.map(|b| b.type_name()).unwrap_or("None")
386 ),
387 )),
388 }
389 } else {
390 Err(Error::new(StatusCode::BadIdentityTokenRejected, format!(
391 "Cannot find endpoint that matches path \"{endpoint_url}\", security policy {security_policy:?}, and security mode {security_mode:?}"
392 )))
393 }
394 }
395
396 pub fn decoding_options(&self) -> DecodingOptions {
398 self.config.decoding_options()
399 }
400
401 async fn authenticate_anonymous_token(
403 &self,
404 endpoint: &ServerEndpoint,
405 token: &AnonymousIdentityToken,
406 ) -> Result<UserToken, Error> {
407 if token.policy_id.as_ref() != POLICY_ID_ANONYMOUS {
408 return Err(Error::new(
409 StatusCode::BadIdentityTokenInvalid,
410 format!(
411 "Token doesn't possess the correct policy id. Got {}, expected {}",
412 token.policy_id.as_ref(),
413 POLICY_ID_ANONYMOUS
414 ),
415 ));
416 }
417 self.authenticator
418 .authenticate_anonymous_token(endpoint)
419 .await?;
420
421 Ok(UserToken(ANONYMOUS_USER_TOKEN_ID.to_string()))
422 }
423
424 async fn authenticate_username_identity_token(
427 &self,
428 endpoint: &ServerEndpoint,
429 token: &UserNameIdentityToken,
430 server_key: &Option<PrivateKey>,
431 server_nonce: &ByteString,
432 ) -> Result<UserToken, Error> {
433 if !self.authenticator.supports_user_pass(endpoint) {
434 Err(Error::new(
435 StatusCode::BadIdentityTokenRejected,
436 "Endpoint doesn't support username password tokens",
437 ))
438 } else if token.policy_id != user_pass_security_policy_id(endpoint) {
439 Err(Error::new(
440 StatusCode::BadIdentityTokenRejected,
441 "Token doesn't possess the correct policy id",
442 ))
443 } else if token.user_name.is_empty() {
444 Err(Error::new(
445 StatusCode::BadIdentityTokenRejected,
446 "User identify token supplied no username",
447 ))
448 } else {
449 debug!(
450 "policy id = {}, encryption algorithm = {}",
451 token.policy_id.as_ref(),
452 token.encryption_algorithm.as_ref()
453 );
454 let token_password = if !token.encryption_algorithm.is_empty() {
455 if let Some(ref server_key) = server_key {
456 let decrypted = user_identity::legacy_decrypt_secret(
457 token,
458 server_nonce.as_ref(),
459 server_key,
460 )?;
461 String::from_utf8(decrypted.value.unwrap_or_default()).map_err(|e| {
462 Error::new(
463 StatusCode::BadIdentityTokenInvalid,
464 format!("Failed to decode identity token to string: {e}"),
465 )
466 })?
467 } else {
468 error!("Identity token password is encrypted but no server private key was supplied");
469 return Err(Error::new(
470 StatusCode::BadIdentityTokenInvalid,
471 "Failed to decrypt identity token password",
472 ));
473 }
474 } else {
475 token.plaintext_password()?
476 };
477
478 self.authenticator
479 .authenticate_username_identity_token(
480 endpoint,
481 token.user_name.as_ref(),
482 &Password::new(token_password),
483 )
484 .await
485 }
486 }
487
488 async fn authenticate_x509_identity_token(
491 &self,
492 endpoint: &ServerEndpoint,
493 token: &X509IdentityToken,
494 user_token_signature: &SignatureData,
495 server_certificate: &Option<X509>,
496 server_nonce: &ByteString,
497 ) -> Result<UserToken, Error> {
498 if !self.authenticator.supports_x509(endpoint) {
499 error!("Endpoint doesn't support x509 tokens");
500 Err(Error::new(
501 StatusCode::BadIdentityTokenRejected,
502 "Endpoint doesn't support x509 tokens",
503 ))
504 } else if token.policy_id.as_ref() != POLICY_ID_X509 {
505 error!("Token doesn't possess the correct policy id");
506 Err(Error::new(
507 StatusCode::BadIdentityTokenRejected,
508 "Token doesn't possess the correct policy id",
509 ))
510 } else {
511 match server_certificate {
512 Some(ref server_certificate) => {
513 let user_identity_tokens = self.authenticator.user_token_policies(endpoint);
515 let security_policy = user_identity_tokens
516 .iter()
517 .find(|t| t.token_type == UserTokenType::Certificate)
518 .map(|t| SecurityPolicy::from_uri(t.security_policy_uri.as_ref()))
519 .unwrap_or_else(|| endpoint.security_policy());
520
521 match security_policy {
523 SecurityPolicy::Unknown | SecurityPolicy::None => Err(Error::new(
524 StatusCode::BadIdentityTokenInvalid,
525 "Bad security policy",
526 )),
527 security_policy => {
528 user_identity::verify_x509_identity_token(
530 token,
531 user_token_signature,
532 security_policy,
533 server_certificate,
534 server_nonce.as_ref(),
535 )
536 }
537 }
538 }
539 None => Err(Error::new(
540 StatusCode::BadIdentityTokenInvalid,
541 "Server certificate missing, cannot validate X509 tokens",
542 )),
543 }?;
544
545 let signing_cert = X509::from_byte_string(&token.certificate_data)?;
547 let signing_thumbprint = signing_cert.thumbprint();
548
549 self.authenticator
550 .authenticate_x509_identity_token(endpoint, &signing_thumbprint)
551 .await
552 }
553 }
554
555 async fn authenticate_issued_identity_token(
556 &self,
557 endpoint: &ServerEndpoint,
558 token: &IssuedIdentityToken,
559 server_key: &Option<PrivateKey>,
560 server_nonce: &ByteString,
561 ) -> Result<UserToken, Error> {
562 if !self.authenticator.supports_issued_token(endpoint) {
563 Err(Error::new(
564 StatusCode::BadIdentityTokenRejected,
565 "Endpoint doesn't support issued tokens",
566 ))
567 } else if token.policy_id != user_pass_security_policy_id(endpoint) {
568 Err(Error::new(
569 StatusCode::BadIdentityTokenRejected,
570 "Token doesn't possess the correct policy id",
571 ))
572 } else {
573 debug!(
574 "policy id = {}, encryption algorithm = {}",
575 token.policy_id.as_ref(),
576 token.encryption_algorithm.as_ref()
577 );
578 let decrypted_token = if !token.encryption_algorithm.is_empty() {
579 if let Some(ref server_key) = server_key {
580 user_identity::legacy_decrypt_secret(token, server_nonce.as_ref(), server_key)?
581 } else {
582 error!("Identity token password is encrypted but no server private key was supplied");
583 return Err(Error::new(
584 StatusCode::BadIdentityTokenInvalid,
585 "Failed to decrypt identity token issued token",
586 ));
587 }
588 } else {
589 token.token_data.clone()
590 };
591
592 self.authenticator
593 .authenticate_issued_identity_token(endpoint, &decrypted_token)
594 .await
595 }
596 }
597
598 pub(crate) fn initial_encoding_context(&self) -> ContextOwned {
599 ContextOwned::new(
601 NamespaceMap::new(),
602 self.type_loaders.read().clone(),
603 self.decoding_options(),
604 )
605 }
606
607 pub fn add_type_loader(&self, type_loader: Arc<dyn TypeLoader>) {
612 self.type_loaders.write().add(type_loader);
613 }
614
615 pub fn summary(&self) -> &ServerDiagnosticsSummary {
617 &self.diagnostics.summary
618 }
619
620 }