PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
kcenon::pacs::security::atna_service_auditor Class Reference

High-level facade for emitting ATNA audit events from DICOM services. More...

#include <atna_service_auditor.h>

Collaboration diagram for kcenon::pacs::security::atna_service_auditor:
Collaboration graph

Public Member Functions

 atna_service_auditor (const syslog_transport_config &config, std::string audit_source_id)
 Construct an auditor with syslog transport configuration.
 
 ~atna_service_auditor ()=default
 
 atna_service_auditor (const atna_service_auditor &)=delete
 
atna_service_auditoroperator= (const atna_service_auditor &)=delete
 
 atna_service_auditor (atna_service_auditor &&) noexcept
 
atna_service_auditoroperator= (atna_service_auditor &&) noexcept
 
void audit_instance_stored (const std::string &source_ae, const std::string &dest_ae, const std::string &study_uid, const std::string &patient_id, bool success)
 Audit a C-STORE (DICOM Instances Transferred) event.
 
void audit_query (const std::string &calling_ae, const std::string &called_ae, const std::string &query_level, bool success)
 Audit a C-FIND (Query) event.
 
void audit_authentication (const std::string &user_id, bool is_login, bool success)
 Audit a User Authentication event.
 
void audit_security_alert (const std::string &user_id, const std::string &alert_description)
 Audit a Security Alert event (e.g., access denied)
 
void set_enabled (bool enabled) noexcept
 Enable or disable audit event emission.
 
bool is_enabled () const noexcept
 Check if audit event emission is enabled.
 
size_t events_sent () const noexcept
 Get the number of audit events successfully sent.
 
size_t events_failed () const noexcept
 Get the number of audit event send failures.
 
void reset_statistics () noexcept
 Reset statistics counters.
 
const std::string & audit_source_id () const noexcept
 Get the audit source identifier.
 
const atna_syslog_transporttransport () const noexcept
 Get the underlying transport (for advanced use)
 

Private Member Functions

void send_audit (const atna_audit_message &message)
 Send an audit message via syslog transport.
 

Private Attributes

std::string audit_source_id_
 Audit source identifier (e.g., "PACS_SYSTEM_01")
 
atna_syslog_transport transport_
 Syslog transport for sending audit messages.
 
std::atomic< bool > enabled_ {true}
 Whether audit is enabled.
 
std::atomic< size_t > events_sent_ {0}
 Statistics.
 
std::atomic< size_t > events_failed_ {0}
 

Detailed Description

High-level facade for emitting ATNA audit events from DICOM services.

Combines the audit message generator (atna_audit_logger) with the syslog transport (atna_syslog_transport) to provide simple, one-call audit methods for common DICOM operations.

Usage

config.host = "audit-server.hospital.local";
config.port = 6514;
atna_service_auditor auditor(config, "PACS_SYSTEM_01");
// After a C-STORE operation:
auditor.audit_instance_stored("MODALITY_01", "PACS_SCP",
"1.2.3.4.5", "PAT001", true);
// After a C-FIND operation:
auditor.audit_query("WORKSTATION_01", "PACS_SCP",
"STUDY", true);
High-level facade for emitting ATNA audit events from DICOM services.
@ tls
TLS over TCP (RFC 5425) — Secure.
Configuration for the Syslog transport.
syslog_transport_protocol protocol
Transport protocol (UDP or TLS)
uint16_t port
Port number (514 for UDP, 6514 for TLS per IANA)
std::string host
Audit Record Repository hostname or IP.

Definition at line 52 of file atna_service_auditor.h.

Constructor & Destructor Documentation

◆ atna_service_auditor() [1/3]

kcenon::pacs::security::atna_service_auditor::atna_service_auditor ( const syslog_transport_config & config,
std::string audit_source_id )

Construct an auditor with syslog transport configuration.

Parameters
configSyslog transport configuration
audit_source_idIdentifier for this audit source (e.g., "PACS_01")

Definition at line 14 of file atna_service_auditor.cpp.

18 transport_(config) {}
std::string audit_source_id_
Audit source identifier (e.g., "PACS_SYSTEM_01")
const std::string & audit_source_id() const noexcept
Get the audit source identifier.
atna_syslog_transport transport_
Syslog transport for sending audit messages.

◆ ~atna_service_auditor()

kcenon::pacs::security::atna_service_auditor::~atna_service_auditor ( )
default

◆ atna_service_auditor() [2/3]

kcenon::pacs::security::atna_service_auditor::atna_service_auditor ( const atna_service_auditor & )
delete

◆ atna_service_auditor() [3/3]

kcenon::pacs::security::atna_service_auditor::atna_service_auditor ( atna_service_auditor && other)
noexcept

Definition at line 20 of file atna_service_auditor.cpp.

22 : audit_source_id_(std::move(other.audit_source_id_)),
23 transport_(std::move(other.transport_)),
24 enabled_(other.enabled_.load(std::memory_order_relaxed)),
25 events_sent_(other.events_sent_.load(std::memory_order_relaxed)),
26 events_failed_(other.events_failed_.load(std::memory_order_relaxed)) {}
std::atomic< bool > enabled_
Whether audit is enabled.
std::atomic< size_t > events_sent_
Statistics.

Member Function Documentation

◆ audit_authentication()

void kcenon::pacs::security::atna_service_auditor::audit_authentication ( const std::string & user_id,
bool is_login,
bool success )

Audit a User Authentication event.

Parameters
user_idUser identifier (AE title or username)
is_logintrue for login, false for logout
successWhether the authentication succeeded

Definition at line 101 of file atna_service_auditor.cpp.

104 {
105
106 if (!enabled_.load(std::memory_order_relaxed)) {
107 return;
108 }
109
110 auto outcome = success ? atna_event_outcome::success
112
115 user_id,
116 "", // user IP (not available at this level)
117 is_login,
118 outcome);
119
120 send_audit(msg);
121}
static atna_audit_message build_user_authentication(const std::string &source_id, const std::string &user_id, const std::string &user_ip, bool is_login, atna_event_outcome outcome=atna_event_outcome::success)
Build User Authentication audit message (login/logout)
void send_audit(const atna_audit_message &message)
Send an audit message via syslog transport.

References audit_source_id_, kcenon::pacs::security::atna_audit_logger::build_user_authentication(), enabled_, send_audit(), kcenon::pacs::security::serious_failure, and kcenon::pacs::security::success.

Here is the call graph for this function:

◆ audit_instance_stored()

void kcenon::pacs::security::atna_service_auditor::audit_instance_stored ( const std::string & source_ae,
const std::string & dest_ae,
const std::string & study_uid,
const std::string & patient_id,
bool success )

Audit a C-STORE (DICOM Instances Transferred) event.

Parameters
source_aeCalling AE title (sender)
dest_aeCalled AE title (receiver)
study_uidStudy Instance UID
patient_idPatient ID (optional, empty if unavailable)
successWhether the operation succeeded

Definition at line 48 of file atna_service_auditor.cpp.

53 {
54
55 if (!enabled_.load(std::memory_order_relaxed)) {
56 return;
57 }
58
61
64 source_ae, // source AE
65 "", // source IP (not available at service level)
66 dest_ae, // destination AE
67 "", // destination IP (not available at service level)
68 study_uid,
69 patient_id,
70 true, // is_import (SCP receiving)
71 outcome);
72
73 send_audit(msg);
74}
static atna_audit_message build_dicom_instances_transferred(const std::string &source_id, const std::string &source_ae, const std::string &source_ip, const std::string &dest_ae, const std::string &dest_ip, const std::string &study_uid, const std::string &patient_id="", bool is_import=true, atna_event_outcome outcome=atna_event_outcome::success)
Build DICOM Instances Transferred audit message (C-STORE, C-MOVE)

References audit_source_id_, kcenon::pacs::security::atna_audit_logger::build_dicom_instances_transferred(), enabled_, send_audit(), kcenon::pacs::security::serious_failure, and kcenon::pacs::security::success.

Referenced by kcenon::pacs::services::storage_scp::handle_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ audit_query()

void kcenon::pacs::security::atna_service_auditor::audit_query ( const std::string & calling_ae,
const std::string & called_ae,
const std::string & query_level,
bool success )

Audit a C-FIND (Query) event.

Parameters
calling_aeCalling AE title (query requester)
called_aeCalled AE title (query responder)
query_levelQuery level string (PATIENT/STUDY/SERIES/IMAGE)
successWhether the operation succeeded

Definition at line 76 of file atna_service_auditor.cpp.

80 {
81
82 if (!enabled_.load(std::memory_order_relaxed)) {
83 return;
84 }
85
88
89 // Use query level as query_data for the audit trail
92 calling_ae,
93 "", // user IP (not available at service level)
94 "QueryLevel=" + query_level + " CalledAE=" + called_ae,
95 "", // patient_id (not available from query keys here)
96 outcome);
97
98 send_audit(msg);
99}
static atna_audit_message build_query(const std::string &source_id, const std::string &user_id, const std::string &user_ip, const std::string &query_data, const std::string &patient_id="", atna_event_outcome outcome=atna_event_outcome::success)
Build Query audit message (C-FIND, QIDO-RS)

References audit_source_id_, kcenon::pacs::security::atna_audit_logger::build_query(), enabled_, send_audit(), kcenon::pacs::security::serious_failure, and kcenon::pacs::security::success.

Referenced by kcenon::pacs::services::query_scp::handle_message().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ audit_security_alert()

void kcenon::pacs::security::atna_service_auditor::audit_security_alert ( const std::string & user_id,
const std::string & alert_description )

Audit a Security Alert event (e.g., access denied)

Parameters
user_idUser identifier
alert_descriptionDescription of the security alert

Definition at line 123 of file atna_service_auditor.cpp.

125 {
126
127 if (!enabled_.load(std::memory_order_relaxed)) {
128 return;
129 }
130
133 user_id,
134 "", // user IP (not available at this level)
135 alert_description);
136
137 send_audit(msg);
138}
static atna_audit_message build_security_alert(const std::string &source_id, const std::string &user_id, const std::string &user_ip, const std::string &alert_description, atna_event_outcome outcome=atna_event_outcome::serious_failure)
Build Security Alert audit message.

References audit_source_id_, kcenon::pacs::security::atna_audit_logger::build_security_alert(), enabled_, and send_audit().

Here is the call graph for this function:

◆ audit_source_id()

const std::string & kcenon::pacs::security::atna_service_auditor::audit_source_id ( ) const
nodiscardnoexcept

Get the audit source identifier.

Definition at line 173 of file atna_service_auditor.cpp.

173 {
174 return audit_source_id_;
175}

References audit_source_id_.

◆ events_failed()

size_t kcenon::pacs::security::atna_service_auditor::events_failed ( ) const
nodiscardnoexcept

Get the number of audit event send failures.

Definition at line 160 of file atna_service_auditor.cpp.

160 {
161 return events_failed_.load(std::memory_order_relaxed);
162}

References events_failed_.

◆ events_sent()

size_t kcenon::pacs::security::atna_service_auditor::events_sent ( ) const
nodiscardnoexcept

Get the number of audit events successfully sent.

Definition at line 156 of file atna_service_auditor.cpp.

156 {
157 return events_sent_.load(std::memory_order_relaxed);
158}

References events_sent_.

◆ is_enabled()

bool kcenon::pacs::security::atna_service_auditor::is_enabled ( ) const
nodiscardnoexcept

Check if audit event emission is enabled.

Returns
true if enabled

Definition at line 148 of file atna_service_auditor.cpp.

148 {
149 return enabled_.load(std::memory_order_relaxed);
150}

References enabled_.

◆ operator=() [1/2]

atna_service_auditor & kcenon::pacs::security::atna_service_auditor::operator= ( atna_service_auditor && other)
noexcept

Definition at line 28 of file atna_service_auditor.cpp.

29 {
30 if (this != &other) {
31 audit_source_id_ = std::move(other.audit_source_id_);
32 transport_ = std::move(other.transport_);
33 enabled_.store(other.enabled_.load(std::memory_order_relaxed),
34 std::memory_order_relaxed);
35 events_sent_.store(other.events_sent_.load(std::memory_order_relaxed),
36 std::memory_order_relaxed);
37 events_failed_.store(
38 other.events_failed_.load(std::memory_order_relaxed),
39 std::memory_order_relaxed);
40 }
41 return *this;
42}

References kcenon::pacs::security::other.

◆ operator=() [2/2]

atna_service_auditor & kcenon::pacs::security::atna_service_auditor::operator= ( const atna_service_auditor & )
delete

◆ reset_statistics()

void kcenon::pacs::security::atna_service_auditor::reset_statistics ( )
noexcept

Reset statistics counters.

Definition at line 164 of file atna_service_auditor.cpp.

164 {
165 events_sent_.store(0, std::memory_order_relaxed);
166 events_failed_.store(0, std::memory_order_relaxed);
167}

References events_failed_, and events_sent_.

◆ send_audit()

void kcenon::pacs::security::atna_service_auditor::send_audit ( const atna_audit_message & message)
private

Send an audit message via syslog transport.

Converts the message to XML and sends it. Updates statistics.

Parameters
messageThe audit message to send

Definition at line 185 of file atna_service_auditor.cpp.

185 {
186 auto xml = atna_audit_logger::to_xml(message);
187 auto result = transport_.send(xml);
188
189 if (result.is_ok()) {
190 events_sent_.fetch_add(1, std::memory_order_relaxed);
191 } else {
192 events_failed_.fetch_add(1, std::memory_order_relaxed);
193 }
194}
static std::string to_xml(const atna_audit_message &message)
Serialize an audit message to RFC 3881 XML.
kcenon::pacs::VoidResult send(const std::string &xml_message)
Send an RFC 3881 XML audit message via Syslog.

References events_failed_, events_sent_, kcenon::pacs::security::atna_syslog_transport::send(), kcenon::pacs::security::atna_audit_logger::to_xml(), and transport_.

Referenced by audit_authentication(), audit_instance_stored(), audit_query(), and audit_security_alert().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_enabled()

void kcenon::pacs::security::atna_service_auditor::set_enabled ( bool enabled)
noexcept

Enable or disable audit event emission.

When disabled, audit methods return immediately without generating or sending any messages. Useful for testing or low-resource environments.

Parameters
enabledtrue to enable, false to disable

Definition at line 144 of file atna_service_auditor.cpp.

144 {
145 enabled_.store(enabled, std::memory_order_relaxed);
146}

◆ transport()

const atna_syslog_transport & kcenon::pacs::security::atna_service_auditor::transport ( ) const
nodiscardnoexcept

Get the underlying transport (for advanced use)

Definition at line 177 of file atna_service_auditor.cpp.

177 {
178 return transport_;
179}

References transport_.

Member Data Documentation

◆ audit_source_id_

std::string kcenon::pacs::security::atna_service_auditor::audit_source_id_
private

Audit source identifier (e.g., "PACS_SYSTEM_01")

Definition at line 199 of file atna_service_auditor.h.

Referenced by audit_authentication(), audit_instance_stored(), audit_query(), audit_security_alert(), and audit_source_id().

◆ enabled_

std::atomic<bool> kcenon::pacs::security::atna_service_auditor::enabled_ {true}
private

Whether audit is enabled.

Definition at line 205 of file atna_service_auditor.h.

205{true};

Referenced by audit_authentication(), audit_instance_stored(), audit_query(), audit_security_alert(), and is_enabled().

◆ events_failed_

std::atomic<size_t> kcenon::pacs::security::atna_service_auditor::events_failed_ {0}
private

Definition at line 209 of file atna_service_auditor.h.

209{0};

Referenced by events_failed(), reset_statistics(), and send_audit().

◆ events_sent_

std::atomic<size_t> kcenon::pacs::security::atna_service_auditor::events_sent_ {0}
private

Statistics.

Definition at line 208 of file atna_service_auditor.h.

208{0};

Referenced by events_sent(), reset_statistics(), and send_audit().

◆ transport_

atna_syslog_transport kcenon::pacs::security::atna_service_auditor::transport_
private

Syslog transport for sending audit messages.

Definition at line 202 of file atna_service_auditor.h.

Referenced by send_audit(), and transport().


The documentation for this class was generated from the following files: