Skip to content

MDEV-35254 Make iterations count configurable in PARSEC plugin#4504

Open
deo002 wants to merge 5 commits into
MariaDB:mainfrom
deo002:feature/parsec_iterations
Open

MDEV-35254 Make iterations count configurable in PARSEC plugin#4504
deo002 wants to merge 5 commits into
MariaDB:mainfrom
deo002:feature/parsec_iterations

Conversation

@deo002

@deo002 deo002 commented Dec 30, 2025

Copy link
Copy Markdown
Contributor
  • The Jira issue number for this PR is: MDEV-35254

Description

Currently it is not possible with the PARSEC plugin to define the number of iterations to be used when generating the key corresponding to the password.

To ensure proper security for users long term, the PARSEC plugin should allow specifying the number of iterations. Additionally, the default should be something more secure.

This patch adds a global plugin variable parsec_iterations to define define the number of iterations to be used when generating the key corresponding to the password. It has a default value, lower and upper bounds.

Basing the PR against the correct MariaDB version

  • This is a new feature or a refactoring, and the PR is based against the main branch.
  • This is a bug fix, and the PR is based against the earliest maintained branch in which the bug can be reproduced.

PR quality check

  • I checked the CODING_STANDARDS.md file and my PR conforms to this where appropriate.
  • For any trivial modifications to the PR, I am ok with the reviewer making the changes themselves.

@deo002 deo002 force-pushed the feature/parsec_iterations branch 4 times, most recently from 910d32e to c425564 Compare January 1, 2026 11:35
@deo002

deo002 commented Jan 1, 2026

Copy link
Copy Markdown
Contributor Author

@deo002 deo002 marked this pull request as ready for review January 1, 2026 12:01
@deo002 deo002 force-pushed the feature/parsec_iterations branch from c425564 to 087c1fa Compare January 2, 2026 09:07
@gkodinov gkodinov added the External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements. label Jan 5, 2026

@gkodinov gkodinov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please make sure the tests are passing. There are some parsec related failures as a result of your changes in buildbot.

@deo002

deo002 commented Jan 5, 2026

Copy link
Copy Markdown
Contributor Author

Hi @gkodinov ,
Looking into it!

@deo002

deo002 commented Jan 5, 2026

Copy link
Copy Markdown
Contributor Author

@gkodinov The PARSEC tests are failing because the current mariadb-connector-c PARSEC implementation enforces a maximum iteration factor of 3. The tests pass locally with the updated Connector/C, and and will pass in CI once PR is merged and the submodule is updated.

@deo002 deo002 force-pushed the feature/parsec_iterations branch from 087c1fa to 0d033e0 Compare January 5, 2026 19:20

@gkodinov gkodinov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

OK, I'll leave that to the final reviewer. Still learning how CI works. OK as far as the preliminary review goes.

@gkodinov gkodinov dismissed their stale review January 6, 2026 11:43

Apparently this is an architectural issue with buildbot. Leaving it to the final reviewer.

@FooBarrior FooBarrior self-requested a review January 6, 2026 16:22
@@ -0,0 +1,86 @@
#
# Test for MDEV-35254: PARSEC plugin should allow DBAs to specify number of iterations

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

note this could have been included in the existing test case parsec.test.

Tests would normally echo this line rather than it being a comment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Right you are @grooverdan.

@deo002 please start the line with --echo, without "Testg for":

--echo MDEV-35254: PARSEC plugin should allow....

Include this test into parsec.test.

drop user t_iter@'%';

-- echo #
-- echo # Preserve the state that existed before the test case was executed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no need to echo non-test information.

-- echo # Preserve the state that existed before the test case was executed
-- echo #

set global parsec_iterations = 262144;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we'd normally save the default global value as user variable at the beginning of the test and set it back at the end. This enables a change in default without changing the test case.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

An end of tests would normally include a --echo # End of 12.4 tests statement to make the test case easier to merge if in future tests are added in later versions.

Comment thread plugin/auth_parsec/server_parsec.cc Outdated
Comment thread plugin/auth_parsec/server_parsec.cc Outdated


static void update_parsec_iterations(MYSQL_THD thd,
struct st_mysql_sys_var *var __attribute__((unused)),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

you do not need var __attribute__((unused)), , it can be just struct st_mysql_sys_var *,. It is C++, after all

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

even me that's what i thought in the first place

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm afraid it cannot -- we have buld issues with unused variables and, sometimes, functions. Most likely because we have the waning switch turned on manually in cmake. I don't like it either, but that's what we have.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So we need this gcc-ism

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

do we? I thought it's standard C++ and a common pattern we already use. What build issues?

@gkodinov gkodinov requested review from vaintroub and removed request for vaintroub January 7, 2026 10:11

@FooBarrior FooBarrior left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good start!
Lots of comments, enough for now, then we'll do another iteration

@@ -0,0 +1,86 @@
#
# Test for MDEV-35254: PARSEC plugin should allow DBAs to specify number of iterations

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Right you are @grooverdan.

@deo002 please start the line with --echo, without "Testg for":

--echo MDEV-35254: PARSEC plugin should allow....

Include this test into parsec.test.

--echo #

--error ER_INCORRECT_GLOBAL_LOCAL_VAR
select @@session.parsec_iterations;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We agreed with @vuvova that setting session value should be made possible: there can be special users that require more hardened security, like admin roles.

Comment thread plugin/auth_parsec/server_parsec.cc Outdated


static void update_parsec_iterations(MYSQL_THD thd,
struct st_mysql_sys_var *var __attribute__((unused)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm afraid it cannot -- we have buld issues with unused variables and, sometimes, functions. Most likely because we have the waning switch turned on manually in cmake. I don't like it either, but that's what we have.

Comment thread plugin/auth_parsec/server_parsec.cc Outdated


static void update_parsec_iterations(MYSQL_THD thd,
struct st_mysql_sys_var *var __attribute__((unused)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So we need this gcc-ism

Comment thread plugin/auth_parsec/server_parsec.cc Outdated
static MYSQL_SYSVAR_UINT(iterations, iterations, PLUGIN_VAR_NOCMDOPT,
"Number of iterations to be used when generating the key corresponding to the password",
NULL, update_parsec_iterations, PARSEC_ITERATIONS_DEFAULT, PARSEC_ITERATIONS_MIN,
PARSEC_ITERATIONS_MAX, PARSEC_ITERATIONS_STEP);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can PARSEC_ITERATIONS_STEP be anything but 1? If not, then the existence of this variable confuses more, than if it was just "1" here

Comment thread plugin/auth_parsec/server_parsec.cc Outdated

constexpr unsigned int PARSEC_ITERATIONS_DEFAULT= 1u << 18;
constexpr unsigned int PARSEC_ITERATIONS_MIN= 1u << 10;
constexpr unsigned int PARSEC_ITERATIONS_MAX= 1u << 19;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this isn't a correct max value. To stay on the safe side, make it 1<<31, and that'll be our technical limitation of 32-bit int (because of my_bit.h function)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There's a slight problem for showing values above 9 in the auth string. I can do it via a hex style encoding:
0–9 → 0..9
A–V → 10..31
Thoughts?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All the symbols from ascii'0' to ascii'z' are printable, so what we have will already work fine.

I.e. ascii'0' + iterations - base.
@vuvova agree?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We will require a little change. After '9', we have some symbols like ':', ';'...etc after which we have 'A', 'B', ...

@FooBarrior FooBarrior Jan 7, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

After '9', we have some symbols like ':', ';'

exactly.

@FooBarrior FooBarrior Jan 7, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh, my bad! Our format
XY:salt:hash

Allows storing an arbitrary number in y. That is, for X=P, that is PBKDF2, and unadjusted iterations power Y=27, it'll be P27:salt:hash

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We have no other algorithm than P right now, but in allows an arbitrary config line in the first part. For P=PBKDF2, it's only an iterations count

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh, my bad! Our format XY:salt:hash

Allows storing an arbitrary number in y. That is, for X=P, that is PBKDF2, and unadjusted iterations power Y=27, it'll be P27:salt:hash

I think 27 might be a slip - shouldn't it be 21(31 - 10)?

@FooBarrior FooBarrior Jan 7, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@deo002, We had a talk with @vuvova

MDEV-32618 declares the format
concat('P', conv(log2(iterations)-10, 10, 62), ':', base64(salt), ':', base64(hash))

that is, the format is conv(log2(iterations)-10, 10, 62)

Which is base62 and is 0..9,A..Z,a..z as you suggested ☺️ 👍

Feel free to use _dig_vec_base62 which is declared in m_string.h and is defined in int2str.cc. And str2int for the backward conversion.

Comment thread plugin/auth_parsec/server_parsec.cc Outdated
constexpr size_t CLIENT_RESPONSE_LENGTH= CHALLENGE_SCRAMBLE_LENGTH
+ ED25519_SIG_LENGTH;

constexpr unsigned int PARSEC_ITERATIONS_DEFAULT= 1u << 18;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Make a parsec_iterations_t type and alias it to uint32

Comment thread plugin/auth_parsec/server_parsec.cc Outdated
Comment thread plugin/auth_parsec/server_parsec.cc Outdated
constexpr size_t CLIENT_RESPONSE_LENGTH= CHALLENGE_SCRAMBLE_LENGTH
+ ED25519_SIG_LENGTH;

constexpr unsigned int PARSEC_ITERATIONS_DEFAULT= 1u << 18;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Default should be the old default value. 1024, IIRC? that is, 1u<<ITER_FACTOR_BASE_VAL

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, it was 1024. I thought of keeping it close to the OWASP's recommended value for PBKDF2-HMAC-SHA512(210,000) as stated in the Jira ticket.

Comment thread plugin/auth_parsec/server_parsec.cc Outdated
assert(params->algorithm == 'P');
int ret = PKCS5_PBKDF2_HMAC(password, (int)pass_len, params->salt,
sizeof(params->salt), 1024 << params->iterations,
sizeof(params->salt), 1024u << params->iterations,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

(1<<ITER_BASE_VAL)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Or maybe PARSEC_ITERATIONS_MIN, if that'll be an alias

@FooBarrior FooBarrior Jan 7, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would maybe suggest renaming PARSEC_ITERATIONS_MIN -> ITER_BASE_VAL. So we'll have this one, and FACTOR one: ITER_FACTOR_BASE_VAL. And use ITER_BASE_VAL as min value in system variable declaration.

@FooBarrior FooBarrior left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Forgot to press "request changes"

FooBarrior

This comment was marked as duplicate.

@deo002 deo002 force-pushed the feature/parsec_iterations branch 3 times, most recently from 2be048a to eaaa106 Compare January 22, 2026 16:36
@deo002 deo002 requested a review from FooBarrior January 22, 2026 18:36

@gkodinov gkodinov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For the sake of process, I'd like to mark the preliminary review as done. I see that the final review is in full swing. Please keep working with the other reviewers.

@gkodinov gkodinov requested review from vuvova and removed request for FooBarrior March 24, 2026 12:47
Comment thread plugin/auth_parsec/server_parsec.cc Outdated


static void update_parsec_iterations(MYSQL_THD thd,
struct st_mysql_sys_var *var __attribute__((unused)),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

do we? I thought it's standard C++ and a common pattern we already use. What build issues?

Comment thread plugin/auth_parsec/server_parsec.cc Outdated
/*
copied from my_bit.h and m_string.h because making a service
will be an overkill
*/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why not include my_bit.h? it looks like a clean header, no dependencies

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ABI may break if the my_bit.h's definitions change between versions. Although, it is extremely unlikely that they will ever change. Will add it as a header.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

My bad, ABI is not a concern here. All are inline functions, compiled into the caller.

@deo002 deo002 Apr 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Tried including my_bit.h directly (requires my_global.h as a prerequisite). This caused a Windows build failure. Any suggestions on how should I proceed? @vuvova

@vuvova vuvova Apr 8, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no, don't include my_global.h, if you cannot use my_bit.h without it then better revert to local functions.

But why my_bit.h needs my_global.h ? if it's only because of uchar/uint/ulonglong then you can either

  • typedef them in the plugin, or
  • change my_bit.h to use unsigned char, unigned int, etc., making it independent from my_global.h

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Got it! Thanks!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I made my_bit.h standalone. I changed to unsigned char, unsigned int etc, but also had to change some macros like C_MODE_START, C_MODE_END, CONSTEXPR. Please let me know if this change is ok.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Parsec already uses ma_global.h from libmariadb. Perhaps it's fine to use it here either?
my_global.h lies in the same directory as my_bit.h: in root/include. If my_bit.h is fine to include, then why my_global.h is not?

auto stored= (Passwd_as_stored*)hash;
auto memory= (Passwd_in_memory*)out;
const uchar ITER_MAX_VAL= parsec_dig_vec_base62[parsec_bit_log2_uint32(PARSEC_ITERATIONS_MAX) - ITER_FACTOR_BASE_VAL];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd add

static_assert(ITER_MAX_VAL == 'z');

just in case

Comment thread plugin/auth_parsec/server_parsec.cc Outdated
}

static MYSQL_THDVAR_UINT(iterations, PLUGIN_VAR_NOCMDOPT,
"Number of iterations to be used when generating the key corresponding to the password",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

perhaps, add ". Must be a power of two". Or ". Will be rounded up to a power of two"

Comment thread plugin/auth_parsec/server_parsec.cc Outdated
parsec_iterations_t iterations_user_input= *static_cast<const parsec_iterations_t *>(save);
parsec_iterations_t iterations= parsec_round_up_to_next_power(iterations_user_input);
if (iterations != iterations_user_input)
my_printf_error(ER_WRONG_VALUE_FOR_VAR, "parsec: parsec_iterations rounded up to %d (next supported value)",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

remove "parsec: " prefix, it's redundant. And may be " (next supported value)" too, because the variable help text should say that, not a warning message after the fact

Comment thread mysql-test/suite/plugins/t/parsec.test Outdated
source include/wait_until_count_sessions.inc;
drop user test2@'%';

--echo # Test for MDEV-35254: PARSEC plugin should allow DBAs to specify number of iterations

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

three-line header:

--echo #
--echo # MDEV-35254 PARSEC plugin should allow DBAs to specify number of iterations
--echo #


--echo # parsec_iterations should should not get accidently mutated during user creation
set @iter_before := @@global.parsec_iterations;
create user t_iter@'%' identified via parsec using password('pwd');

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

print the password here, that is,

select left(json_value(...)) from mysql.global.priv where user='t_iter'

to verify that the password indeed has a correct iteration character. Perhaps even repeat it for a couple of different iteration values.

@deo002

deo002 commented Apr 7, 2026

Copy link
Copy Markdown
Contributor Author

Working on it!

@deo002 deo002 force-pushed the feature/parsec_iterations branch 4 times, most recently from 4922a96 to 90fba23 Compare April 9, 2026 04:46

@FooBarrior FooBarrior left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Expressed my concerns, basically directed to @vuvova.

Comment thread include/my_bit.h Outdated
*/

C_MODE_START
MY_BIT_C_MODE_START

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

MY_BIT_C_MODE_START is weird with this MY_BIT prefix. There is nothing specific to MY_BIT in this macro

If you want to avoid duplicate macro definition warning, then either:

  1. #undef macro before #define -- undeffing an undefined macro doesn't produce a new warning
  2. Wrap the definition in #ifndef/#endif

The first solution is one line shorter, but if the definition would change in my_global someday, it would likely not be updated here, and those who are using my_bit.h would end up in stale definition (hiding the one from my_global.h).

So I'd go with #1, however, see my next comment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd do

#ifdef __cplusplus
extern "C" {
#else
#define constexpr
#endif

// all my_bit.h content

#ifdef __cplusplus
}
#else
#undef constexpr
#endif

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

And also uint, uchar,...

And do you suggest to change CONSTEXPR to constexpr?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no uint, no uchar, this is already replaced by unsigned int, unsigned char, etc. only c/c++ changes to make a universal c/c++ header.

Comment thread include/my_bit.h
Comment thread include/my_bit.h Outdated
#ifndef MY_BIT_INCLUDED
#define MY_BIT_INCLUDED

/* C vs C++ */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It would have to be a separate commit

Comment thread include/my_bit.h
@deo002 deo002 force-pushed the feature/parsec_iterations branch 2 times, most recently from 6270e83 to eb5d7a8 Compare April 15, 2026 02:59
@deo002

deo002 commented Apr 15, 2026

Copy link
Copy Markdown
Contributor Author

I have pushed the requested changes. Some tests are failing, they don't seem to be related to this PR.

Comment thread plugin/auth_parsec/server_parsec.cc
@FooBarrior

Copy link
Copy Markdown
Contributor

@deo002 Also put MDEV-35254 in the refactor commit header, that'll make it easier for us to cherry-pick changes if we'll want to.

@deo002 deo002 force-pushed the feature/parsec_iterations branch from eb5d7a8 to d61b6ba Compare April 21, 2026 18:44
@deo002

deo002 commented Apr 22, 2026

Copy link
Copy Markdown
Contributor Author

Done!

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a configurable iteration count for the PARSEC authentication plugin by introducing a new parsec_iterations plugin system variable, plus a new thd_service to let plugins access the current THD and thus session/global sysvars.

Changes:

  • Add parsec_iterations (power-of-two, rounded up) and encode iteration exponent in the stored auth string using base62.
  • Introduce a new plugin service thd_service with get_current_thd() and wire it through the service registry.
  • Update plugin interface version and adjust affected mysql-test expected outputs; refactor my_bit.h helpers for broader (C/C++) usability.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
sql/sql_plugin_services.inl Registers the new thd_service in the server’s exported plugin services list.
sql/sql_class.cc Implements get_current_thd() for the thd_service.
plugin/auth_parsec/server_parsec.cc Adds parsec_iterations sysvar, updates hash format iteration encoding/decoding, and uses thd_service to read THDVAR.
mysql-test/suite/plugins/t/parsec.test Extends PARSEC test coverage to validate sysvar behavior, rounding, and encoding in auth string.
mysql-test/suite/plugins/r/parsec.result Updates expected output for the new PARSEC sysvar tests and warnings.
mysql-test/suite/plugins/r/simple_password_check.result Bumps expected plugin library version due to interface change.
mysql-test/suite/plugins/r/show_all_plugins.result Updates expected plugin library versions.
mysql-test/suite/plugins/r/cracklib_password_check.result Bumps expected plugin library version due to interface change.
mysql-test/suite/plugins/r/auth_ed25519.result Bumps expected plugin library version due to interface change.
mysql-test/main/plugin.result Updates expected plugin library versions.
mysql-test/main/handlersocket.result Updates expected plugin library version.
libservices/thd_service.c Adds SERVICE_VERSION thd_service entry for the new service.
libservices/CMakeLists.txt Builds the new thd_service.c into libservices.
include/service_versions.h Introduces VERSION_thd for service versioning.
include/mysql/services.h Exposes the new service_thd.h via umbrella services header.
include/mysql/service_thd.h Defines the thd_service interface (dynamic macro + static prototype).
include/mysql/plugin.h Bumps MARIA_PLUGIN_INTERFACE_VERSION.
include/mysql/plugin_password_validation.h.pp Regenerates preprocessed plugin header output to include thd_service symbols.
include/mysql/plugin_function.h.pp Same as above.
include/mysql/plugin_ftparser.h.pp Same as above.
include/mysql/plugin_encryption.h.pp Same as above.
include/mysql/plugin_data_type.h.pp Same as above.
include/mysql/plugin_auth.h.pp Same as above.
include/mysql/plugin_audit.h.pp Same as above.
include/my_bit.h Refactors bit utility helpers/types to be usable cleanly from C++ plugin code.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread plugin/auth_parsec/server_parsec.cc Outdated
Comment on lines 247 to 253
const uchar ITER_MAX_VAL= parsec_dig_vec_base62[my_bit_log2_uint32(PARSEC_ITERATIONS_MAX) - ITER_FACTOR_BASE_VAL];
assert(ITER_MAX_VAL == 'L');

if (hash_length != sizeof (*stored) || *out_length < sizeof(*memory) ||
stored->algorithm != 'P' ||
stored->iterations < '0' || stored->iterations > '3' ||
stored->iterations < '0' || stored->iterations > ITER_MAX_VAL ||
stored->colon != ':' || stored->colon2 != ':')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks valid too

Comment on lines +57 to +66
static void update_parsec_iterations(MYSQL_THD thd,
struct st_mysql_sys_var *var, void *var_ptr, const void *save)
{
parsec_iterations_t iterations_user_input= *static_cast<const parsec_iterations_t *>(save);
parsec_iterations_t iterations= my_round_up_to_next_power(iterations_user_input);
if (iterations != iterations_user_input)
my_printf_error(ER_WRONG_VALUE_FOR_VAR, "parsec_iterations rounded up to %d",
ME_WARNING, iterations);
*static_cast<parsec_iterations_t*>(var_ptr)= iterations;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nitpicking. signed/unsigned point is moot if we use a lower MAX value per previous comment

Comment on lines +43 to +46
constexpr parsec_iterations_t ITER_FACTOR_BASE_VAL= 10u;
constexpr parsec_iterations_t ITER_BASE_VAL= 1u << ITER_FACTOR_BASE_VAL;
constexpr parsec_iterations_t PARSEC_ITERATIONS_MAX= 1u << 31;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks valid

Comment thread mysql-test/suite/plugins/t/parsec.test Outdated
set session parsec_iterations = 1024;
select @@session.parsec_iterations;

--echo # parsec_iterations should should not get accidently mutated during user creation
deo002 and others added 4 commits June 17, 2026 22:51
Removed type aliases and macros defined in my_global.h from my_bit.h,
making it possible to include it in plugins or external code without
pulling in my_global.h
This patch adds a global and session level plugin variable
parsec_iterations to define the number of iterations to be
used when generating the key corresponding to the password.
It has a default value, lower and upper bounds.
* reduced PARSEC_ITERATIONS_MAX because PKCS5_PBKDF2_HMAC() takes
  a signed int
* instead of checking for '0'..'L' range (which includes punctuation,
  check for the valid result of base62_to_uchar()
* add a connection test with non-default parsec_iterations

@vuvova vuvova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok, this looks good.

The service should be in a separate commit. Copilot had a couple of good comments.
And an test with an actual connection attempt was missing.

I've rebased on top of main and fixed the above, now it's good for 13.1 and testing.

Comment on lines +43 to +46
constexpr parsec_iterations_t ITER_FACTOR_BASE_VAL= 10u;
constexpr parsec_iterations_t ITER_BASE_VAL= 1u << ITER_FACTOR_BASE_VAL;
constexpr parsec_iterations_t PARSEC_ITERATIONS_MAX= 1u << 31;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks valid

Comment on lines +57 to +66
static void update_parsec_iterations(MYSQL_THD thd,
struct st_mysql_sys_var *var, void *var_ptr, const void *save)
{
parsec_iterations_t iterations_user_input= *static_cast<const parsec_iterations_t *>(save);
parsec_iterations_t iterations= my_round_up_to_next_power(iterations_user_input);
if (iterations != iterations_user_input)
my_printf_error(ER_WRONG_VALUE_FOR_VAR, "parsec_iterations rounded up to %d",
ME_WARNING, iterations);
*static_cast<parsec_iterations_t*>(var_ptr)= iterations;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nitpicking. signed/unsigned point is moot if we use a lower MAX value per previous comment

Comment thread plugin/auth_parsec/server_parsec.cc Outdated
Comment on lines 247 to 253
const uchar ITER_MAX_VAL= parsec_dig_vec_base62[my_bit_log2_uint32(PARSEC_ITERATIONS_MAX) - ITER_FACTOR_BASE_VAL];
assert(ITER_MAX_VAL == 'L');

if (hash_length != sizeof (*stored) || *out_length < sizeof(*memory) ||
stored->algorithm != 'P' ||
stored->iterations < '0' || stored->iterations > '3' ||
stored->iterations < '0' || stored->iterations > ITER_MAX_VAL ||
stored->colon != ':' || stored->colon2 != ':')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks valid too

@vuvova vuvova force-pushed the feature/parsec_iterations branch from d61b6ba to 9800b34 Compare June 17, 2026 20:53
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ deo002
❌ vuvova
You have signed the CLA already but the status is still pending? Let us recheck it.

@deo002

deo002 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

On it! Will push the requested changes soon!
P.S. Just checked, it's all done! Thanks for the fixes and refactor @vuvova

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

Labels

External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements.

Development

Successfully merging this pull request may close these issues.

9 participants