Skip to content

p11_child: Add timeout parameter #7890

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

thalman
Copy link
Contributor

@thalman thalman commented Mar 20, 2025

p11_child communication with OCSP server may take a long time because of network issues. Then p11_child is killed after p11_child_timeout and the authentication fails.

This is not desirable when certificate_verification is set to soft_ocsp. This update will pass the timeout to the child process so it can cancel the OCSP verification before it is terminated.

Resolves: #6601

@alexey-tikhonov
Copy link
Member

@alexey-tikhonov alexey-tikhonov self-requested a review March 20, 2025 18:54
@alexey-tikhonov alexey-tikhonov self-assigned this Mar 20, 2025
@thalman thalman force-pushed the p11_child_timeout branch 2 times, most recently from 56a725f to 220bbaa Compare March 21, 2025 08:30
@@ -582,6 +597,7 @@ errno_t init_p11_ctx(TALLOC_CTX *mem_ctx, const char *ca_db,
return ENOMEM;
}

ctx->start_timestamp = time(NULL);
Copy link
Contributor

Choose a reason for hiding this comment

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

Hi,

why don't you put timeout into struct p11_ctx as well (it would fit into struct cert_verify_opts as well) ? This would help to avoid adding timeout into all the function headers.

bye,
Sumit

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking of that too, I have no preference here. But before proceeding with changes I want to do some testing to see if this solves the issue correctly. This is still draft PR.

Copy link
Member

Choose a reason for hiding this comment

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

I would put this into cert_verify_opts as it would reduce number of changes (this struct is populated already in main()). But I don't insist.

@thalman thalman force-pushed the p11_child_timeout branch from 220bbaa to 1559bdf Compare April 2, 2025 11:29
@thalman thalman marked this pull request as ready for review April 2, 2025 12:22
@alexey-tikhonov
Copy link
Member

@thalman, could you please rebase?

p11_child communication with OCSP server may take a long time
because of network issues. Then p11_child is killed after
`p11_child_timeout` and the authentication fails.

This is not desirable when `certificate_verification` is
set to `soft_ocsp`. This update will pass the timeout to the
child process so it can cancel the OCSP verification
before it is terminated.

Resolves: SSSD#6601
@thalman thalman force-pushed the p11_child_timeout branch from 1559bdf to d1aeb3c Compare April 10, 2025 12:54
@thalman
Copy link
Contributor Author

thalman commented Apr 10, 2025

@thalman, could you please rebase?

Rebased

@alexey-tikhonov alexey-tikhonov added the coverity Trigger a coverity scan label Apr 12, 2025
@@ -59,7 +60,8 @@ enum pin_mode {
};

errno_t init_p11_ctx(TALLOC_CTX *mem_ctx, const char *ca_db,
bool wait_for_card, struct p11_ctx **p11_ctx);
bool wait_for_card, time_t timeout,
Copy link
Member

Choose a reason for hiding this comment

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

Any reason to use time_t specifically and not plain int or unsigned?
This arg is just a period (number of seconds?), not a time point.

Copy link
Member

Choose a reason for hiding this comment

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

Also code parses it as POPT_ARG_LONG, it's better to match types strictly to avoid surprises (especially on non-x86 platforms).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for parsing I use long int but the rest of the code expects int. I did not have particular reason for using time_t I can change that to int and add check that this parameter fits into it.

Copy link
Member

Choose a reason for hiding this comment

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

Would it be possible to simply use int everywhere (including parsing)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And of course because we use time() to calculate the timeout.

Copy link
Member

Choose a reason for hiding this comment

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

That's a rabbit hole. Looks like there is no portable way to increment time_t directly.

Copy link
Member

Choose a reason for hiding this comment

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

Currently it is implicitly cast-ed to time_t from long when provided to do_work(). Maybe that's ok.

@alexey-tikhonov
Copy link
Member

Ha... It appears query_responder() already supports timeout argument, it just wasn't properly provided...

@alexey-tikhonov
Copy link
Member

@spoore1, would you like a test build before we merge this?

/* substract 1 so we finish before child is forcibly terminated */
req_timeout = p11_ctx->timeout - 1 -
(time(NULL) - p11_ctx->start_timestamp);
if (req_timeout < 0) {
Copy link
Member

Choose a reason for hiding this comment

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

Not needed if below condition changed to if (req_timeout <= 0)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With the one item (deadline) approach this changes a bit but the condition is still needed.

Copy link
Member

@alexey-tikhonov alexey-tikhonov Apr 16, 2025

Choose a reason for hiding this comment

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

Only to have a dedicated debug message.
Otherwise instead of two:

if (req_timeout <= 0) {
...
if (req_timeout != 0) {

there could be single

if (req_timeout > 0) { process_responder() }

@@ -1128,7 +1128,7 @@ ifp_users_find_by_valid_cert_send(TALLOC_CTX *mem_ctx,
goto done;
}

state->extra_args = talloc_zero_array(state, const char *, 8);
state->extra_args = talloc_zero_array(state, const char *, 10);
Copy link
Member

@alexey-tikhonov alexey-tikhonov Apr 12, 2025

Choose a reason for hiding this comment

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

Do you think it would be possible to factor out a common helper, that prepares p11_child args, out of ifp/pamsrv_p11/ssh to reduce code copy&paste?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will take a look

@spoore1
Copy link
Contributor

spoore1 commented Apr 13, 2025

@spoore1, would you like a test build before we merge this?

If it's ok if I can't test until Tuesday or Wednesday, yes. I can't guarantee I'll be able to test before that.

@@ -44,8 +44,7 @@ struct p11_ctx {
const char *ca_db;
bool wait_for_card;
struct cert_verify_opts *cert_verify_opts;
time_t start_timestamp;
time_t timeout;
int ocsp_deadline;
Copy link
Member

Choose a reason for hiding this comment

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

Unlike timeout, this is a better fit for time_t, actually (see another comment).

(time(NULL) - p11_ctx->start_timestamp);
if (req_timeout < 0) {
if (p11_ctx->ocsp_deadline != -1 && p11_ctx->cert_verify_opts->soft_ocsp) {
req_timeout = p11_ctx->ocsp_deadline - time(NULL);
Copy link
Member

@alexey-tikhonov alexey-tikhonov Apr 16, 2025

Choose a reason for hiding this comment

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

There is a difftime().
But it returns double.
I now tend to agree to keep everything as time_t and that's it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

smartcard login fails when network disconnected
4 participants