Skip to content

Close the session when login fails in Token.open() - #247

Merged
MatthiasValvekens merged 3 commits into
pyauth:masterfrom
WiktorB2004:fix/close-session-on-login-failure
Oct 25, 2026
Merged

MatthiasValvekens merged 3 commits into
pyauth:masterfrom
WiktorB2004:fix/close-session-on-login-failure

Conversation

@WiktorB2004

Copy link
Copy Markdown
Contributor

Fixes #246

Token.open() opens a session with C_OpenSession and then authenticates with C_Login. When authentication
raised (wrong or locked PIN, user already logged in, or protected authentication requested from a module without
CKF_PROTECTED_AUTHENTICATION_PATH), the exception propagated without closing the session. The caller never gets a
Session object, so the handle stayed open until C_Finalize.

This wraps the authentication block in try ... except BaseException:, calls C_CloseSession and re-raises. The
C_CloseSession return value is ignored on purpose so that it cannot mask the original error. BaseException
also covers KeyboardInterrupt during the (GIL-released) login.

Tests (tests/test_sessions.py, SoftHSMv2 only, like the neighbouring login tests):

  • test_failed_login_does_not_leak_session: a failed user login must not leave a read-only session behind. Detected
    without ctypes: a leftover read-only session makes a following security officer login fail with
    SessionReadOnlyExists.
  • test_unsupported_protected_auth_does_not_leak_session: same for the ArgumentsBad path.

Without the fix both tests fail, and the leaked session also makes later tests in the module fail (test_init_pin,
test_open_session_and_login_so). With the fix the full suite passes on SoftHSM2 2.6.1 (Debian 13, Python 3.13):
147 passed, 18 skipped. I did not run opencryptoki, Windows or macOS locally.

Token.open() opens a session with C_OpenSession and then authenticates
with C_Login. If authentication failed (wrong PIN, locked PIN, user
already logged in, or protected authentication requested from a module
that does not support it), the exception propagated without closing the
session, and since the caller never received a Session object, the
handle stayed open until C_Finalize. Close it before re-raising.

The C_CloseSession return value is ignored on purpose, so that it
cannot mask the original error.

@MatthiasValvekens MatthiasValvekens left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch; I'd factor the fix a bit differently, though.

Comment thread pkcs11/_pkcs11.pyx Outdated
Comment thread tests/test_sessions.py Outdated
@codecov-commenter

codecov-commenter commented Oct 25, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 75.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.32%. Comparing base (fc44b72) to head (3d65d82).
⚠️ Report is 11 commits behind head on master.

Files with missing lines Patch % Lines
pkcs11/_pkcs11.pyx 75.00% 2 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #247      +/-   ##
==========================================
+ Coverage   91.52%   92.32%   +0.80%     
==========================================
  Files          15       15              
  Lines        2713     2788      +75     
  Branches       27       27              
==========================================
+ Hits         2483     2574      +91     
+ Misses        228      212      -16     
  Partials        2        2              
Flag Coverage Δ
unittests 92.32% <75.00%> (+0.80%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Raise ArgumentsBad for an unsupported protected authentication path
before C_OpenSession, and decide on the C_Login result whether to close
the session and raise or to return it, instead of a catch-all except.
@MatthiasValvekens
MatthiasValvekens merged commit c48f796 into pyauth:master Oct 25, 2026
35 checks passed
@WiktorB2004
WiktorB2004 deleted the fix/close-session-on-login-failure branch October 26, 2026 07:51
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.

Token.open() leaks the session when C_Login fails

3 participants