Skip to content

Honor login encryption options for Relog DSN that imports Perfmon - #555

Merged
JosephPilov-MSFT (PiJoCoder) merged 4 commits into
masterfrom
RelogEncryptConnection_pijocoder
Sep 22, 2026
Merged

JosephPilov-MSFT (PiJoCoder) merged 4 commits into
masterfrom
RelogEncryptConnection_pijocoder

Conversation

@PiJoCoder

@PiJoCoder JosephPilov-MSFT (PiJoCoder) commented Sep 1, 2026 •

Copy link
Copy Markdown
Collaborator

Investigation Summary

Investigated whether relog.exe, which SQL Nexus uses to import PerfMon (.blg) data into the repository database, can support encrypted SQL Server connections.

Initial testing of the current SQL Nexus import path showed SQL Server sessions with:

encrypt_option = FALSE

indicating that the existing SQL Nexus configuration is not using SQL Server transport encryption.

To determine whether this was a limitation of Relog itself or of the DSN configuration, a separate test was performed using a manually created ODBC DSN configured with a modern SQL Server ODBC driver and encryption enabled.

relog.exe "D:\SQLLogScout\output\myserver_sql2017cs_20260901T1343469219_Perfmon.out_000001.blg" -f SQL -o SQL:SqlNexusTestDSN!CounterLog

Relog successfully imported the .blg file into SQL Server and populated the expected CounterData and CounterDetails tables. SQL Server subsequently reported:

encrypt_option = TRUE

When I ran this query:

SELECT
    s.session_id,
    s.program_name,
    c.net_transport,
    c.encrypt_option,
    c.auth_scheme
FROM sys.dm_exec_sessions s
JOIN sys.dm_exec_connections c
    ON s.session_id = c.session_id
WHERE s.program_name LIKE '%Windows%'
ORDER BY s.login_time DESC;
Question Result
Can Relog import PerfMon data into SQL Server using a modern ODBC driver? ✅ Yes
Can Relog work with a manually created DSN using ODBC Driver 17/18? ✅ Yes
Can Relog establish an encrypted SQL Server connection? ✅ Yes (encrypt_option = TRUE)
Is Relog inherently limited to unencrypted connections? ❌ No
Is the current SQL Nexus DSN implementation using encryption? ❌ No (observed encrypt_option = FALSE during initial testing)

Root Cause

The ODBC DSN that SQL Nexus auto-creates for relog.exe (in PerfmonImporter.DSNCreator) was:

  • Registered against the legacy "SQL Server" ODBC driver (sqlsrv32.dll), which does not honor modern encryption keywords.
  • Built without the Encrypt / TrustServerCertificate attributes, so it never negotiated transport encryption regardless of how the user connected SQL Nexus to SQL Server.

As a result, the Perfmon import path always connected with encrypt_option = FALSE, even when the rest of the application used an encrypted connection.

Changes

Honor the app's encryption options for the relog DSN

  • BLGImporter now reads Encrypt and TrustServerCertificate from the SQL Nexus connection string (Microsoft.Data.SqlClient, where Encrypt is a SqlConnectionEncryptOption; Mandatory/Strict => encrypt, Optional => no encryption) and propagates them into the DSN, so relog negotiates the same transport security as the rest of the app.
  • DSNCreator appends the Encrypt and TrustServerCertificate keywords to the DSN attribute string.

Future-proof ODBC driver selection

  • The DSN driver is now chosen by enumerating the drivers actually installed on the machine via SQLGetInstalledDrivers, preferring modern "ODBC Driver NN for SQL Server" drivers newest-version-first, with the legacy "SQL Server" driver kept only as a last-resort fallback (and a warning logged if it is used while encryption was requested). A newer driver (19/20/...) is picked up automatically with no code change.
  • If enumeration fails, the code falls back to probing the known driver names (18 -> 17 -> legacy) and logs that it did so.
  • The SQLGetInstalledDrivers result buffer is parsed by walking the double-null-terminated block and stopping at the list terminator, rather than trusting the returned length (whose char/byte semantics are ambiguous across ODBC versions).

Reliability and correctness

  • Fixed a malformed ODBC token in the SQL-authentication DSN path (a stray ; was prefixed onto the UID keyword).
  • The DSN is now created once per import instead of once per file.
  • Import fails closed: if the DSN cannot be created, the import surfaces the failure instead of letting relog run and silently import zero rows.
  • Partial-import status is reported when the user cancels part-way through.
  • The fail-closed encryption-settings logging is null-safe (falls back to Debug.WriteLine when Util.Logger is unset, e.g. outside the WinForms host) so the handler never throws.
  • Renamed the DSN from "Nexus" to "SQLNexusDSN" via a shared constant so the DSN registration and the relog -o SQL:<DSN>!<db> argument stay in sync.

Security / privacy

  • No credentials or connection strings are logged; the relog arguments reference the DSN only, never a password.
  • Modern drivers that enforce encryption are preferred by design; the legacy driver is a fallback only.

Testing

  1. Make sure you capture a SQL LogScout with one ore more .BLG (Perfmon) files and import it via SQL Nexus

  2. While the BLG import is happening, run this query to ensure that the connection for Relog is encrypted:

    SELECT
      s.session_id,
      s.program_name,
      c.net_transport,
      c.encrypt_option,
      c.auth_scheme
    FROM sys.dm_exec_sessions s
    JOIN sys.dm_exec_connections c
      ON s.session_id = c.session_id
    WHERE s.program_name LIKE '%Windows%'
    ORDER BY s.login_time DESC;
  3. Ensure the tables dbo.CounterData, dbo.CounterDetails are populated with data

  4. Use the SQL Nexus reports, e.g. Perfmon Summary, to confirm data is there.

Configure the ODBC DSN used by relog.exe to respect the Encrypt and
Trust Server Certificate options the user selects when connecting
SqlNexus to SQL Server, and modernize DSN driver selection.

Changes:
- BLGImporter: read Encrypt/TrustServerCertificate from the connection
  string and propagate them into the DSN so relog negotiates the same
  transport security as the rest of the app.
- DSNCreator: append Encrypt and TrustServerCertificate keywords; try
  modern drivers first (ODBC Driver 18 -> 17 -> legacy "SQL Server")
  with logging and graceful fallback.
- Extract BuildDsnSettings() as a testable helper (P/Invoke stays out
  of unit tests).
- Rename DSN from "Nexus" to "SQLNexusDSN" via a shared constant so the
  registration and relog "-o SQL:<DSN>!<db>" argument stay in sync.
- Add DSNCreatorTests (6 MSTest cases) and reference PerfmonImporter
  from the unit test project.
@PiJoCoder JosephPilov-MSFT (PiJoCoder) changed the title Honor login encryption options for Perfmon relog DSN Honor login encryption options for Relog DSN that imports Perfmon Sep 3, 2026
…lity fixes, and tests

Improve the ODBC DSN creation used by relog.exe for Perfmon (.blg) import so it is
future-proof, reliable, and fully unit-tested, while preserving the existing DSN
settings and Encrypt / TrustServerCertificate behavior.

DSN driver selection (future-proof):
- Enumerate installed ODBC drivers via SQLGetInstalledDrivers instead of a hardcoded
  list. Prefer modern "ODBC Driver NN for SQL Server" drivers newest-version-first, so
  a future driver (19/20/...) is used automatically with no code change.
- Keep the legacy "SQL Server" driver as a last-resort fallback (it largely ignores
  encryption keywords; warn when used with Encrypt).
- Fall back to probing known driver names if enumeration fails, and log that it did.
- Extract GetPreferredDrivers() as a pure, testable ordering helper.

Reliability / correctness:
- Fix malformed ODBC token in BuildDsnSettings SQL-auth path (stray ';' before UID).
- Create the DSN once per import instead of once per file.
- Report partial-import status when the user cancels part-way through.
- Extract ReadEncryptionSettings() and make its fail-closed logging null-safe so it
  never throws when Util.Logger is unset (e.g. outside the WinForms host).
- Do not log connection strings or credentials.

Tests / infrastructure:
- Add [InternalsVisibleTo] (with public key) so internal helpers are testable.
- Add BLGImporterEncryptionTests and expand DSNCreatorTests to cover driver ordering,
  future versions, empty/null/legacy-only cases, and exact DSN token construction.

All 15 PerfmonImporter unit tests pass; full solution build is clean.
@asavioliMSFT

Copy link
Copy Markdown
Contributor

Testing

Confirmed connection is encrypted

image

loading data took 299 seconds. With old version, it took a little bit longer

image

confirmed both tables are populated CounterData and CounterDetails.

Rowcount matches the current public nexus version

@PiJoCoder
JosephPilov-MSFT (PiJoCoder) merged commit a9adab0 into master Sep 22, 2026
2 of 3 checks passed
@PiJoCoder
JosephPilov-MSFT (PiJoCoder) deleted the RelogEncryptConnection_pijocoder branch September 22, 2026 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Investigate Relog connection details to see if it can support encryption

2 participants