-
-
Notifications
You must be signed in to change notification settings - Fork 828
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
dev/core#2258 - Read+write SMTP password using 'crypto.token' #19239
Conversation
(Standard links)
|
jenkins, test this please |
023c9c1
to
9557c0f
Compare
9557c0f
to
ddf1456
Compare
@totten can you rebase this please |
$settings = self::findSmtpPasswords(); | ||
foreach ($settings as $setting) { | ||
$value = unserialize($setting['value']); | ||
$value['smtpPassword'] = CRM_Utils_Crypt::decrypt($value['smtpPassword']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason why you don't want to call crypto service and encrypt using the new system here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For posterity, we discussed further at https://chat.civicrm.org/civicrm/pl/r8pbskapc7gybngdceqxg9sksh
Basically, we're evaluating trade-off between:
- SITE_KEY as fallback crypto key
- How: Register
SITE_KEY
as low-priority crypto-key for use withCRED
. The upgrader uses this for initial encryption ofsmtpPassword
- Pro: The
smtpPassword
is promptly (re)encrypted. No interregnum. - Con: Creates more edge-cases / complexity
- How: Register
- Temporary decryption
- How: The upgrader decrypts
smtpPassword
. After upgrade, sysadmin defines CRED_KEYS and runsrotateKey
- Pro: Long-term, system is simpler to understand / has fewer edge-cases (for admin/dev/etc)
- Con: There's an interregnum (between the upgrade and encryption) during which
smtpPassword
is stored as plaintext.
- How: The upgrader decrypts
ddf1456
to
9b645a5
Compare
Based on discussion with Tim I'm ok with this now, MOP |
Before ------ The format of the 'smtpPassword' subfield depends on the available PECL extensions: * The field is ciphertext... if PHP has `mcrypt` enabled * The field is plaintext... if PHP has `mcrypt` disabled After ----- The format of the `smtpPassword` subfield is specified by `crypto.token` which means: * The field is ciphertext... if it begins with `chr(2)` * The field is plaintext... if it begins with any printable character
9b645a5
to
aa7a657
Compare
Merging per MOP |
Overview
This converts the
smtpPassword
subfield fromCRM_Utils_Crypt
to thecrypto.token
service, which means:smtpPassword
in SQL, the on-disk format is less ambiguous.smtpPassword
incivicrm.settings.php
, the on-disk format is less ambiguous and more forgiving.See also: https://lab.civicrm.org/dev/core/-/issues/2258
(NOTE: This depends on #19236 an #19251.)
(NOTE: A few edits added to the description after-the-fact. It originally spoke of the old plaintext as, well, plaintext. It was actually Base64-encoded plaintext.)
Before
The format of the
smtpPassword
subfield depends on the available PHP/PECL extensions:mcrypt
disabledmcrypt
enabledAdditionally, note that:
YWJjZGVm
is random password or ciphertext. It remains legible only as long as both the PHP configuration and SITE_KEY stay the same.After
The format of the
smtpPassword
subfield is specified bycrypto.token
which means:chr(2)
).chr(2)
(in which case the string looks like^CTK?k=<keyid>&t=<ciphertext>
)Additionally, note that:
System.rotateKey
API can be used to phase-out old keys (per (dev/core#2258) Add API+hook to rotate keys for encrypted fields #19251).Technical Details: Review of upgrade scenarios
There are three variables which determine different upgrade scenarios:
civicrm_settings
) or in PHP (civicrm.settings.php
)?mcrypt
(ie the old crypto system) enabled?CIVICRM_CRED_KEYS
(ie the new crypto system)?Here are how the scenarios work out:
civicrm_settings
)smtpPassword
starts as Base64 plain-text and ends as normal plain-text.civicrm_settings
)smtpPassword
converts from plain-text to new-encryption.civicrm_settings
)smtpPassword
converts from old-encryption to plain-text.civicrm_settings
)smtpPassword
converts from old-encryption to new-encryption.civicrm.settings.php
)smtpPassword
was stored in PHP as plain-text, and the same plain-text will work post-upgrade.smtpPassword
was stored in PHP with the old Base64 plain-text, and the upgrader cannot change it. After upgrading, you must manually editcivicrm.settings.php
to setsmtpPassword
as normal plain-text.civicrm.settings.php
)smtpPassword
was stored in PHP with the old encrypted format, and the upgrader cannot change it. After upgrading, you must manually editcivicrm.settings.php
to setsmtpPassword
using plain-text or the new encryption format.Scenarios 1-4 all end with a working/readable variant of
smtpPassword
. After upgrade, one has the option to change the crypto by updatingCIVICRM_CRED_KEYS
and callingSystem.rotateKeys
.Scenarios 5-6 are annoying, but there's not much we can do besides show a warning. However, I don't expect this to be common because it has always been tricky to understand/setup. If you have managed to figure it out before, then you're probably clever enough to sort out the migration - as long as you see the warning provided by the upgrader. (There are more comments in
ThirtyFour.php
alongside the relevant warning.)Technical Details: Sysadmin usability
This patch incidentally makes it easier to set the SMTP password via
civicrm.settings.php
/$civicrm_settings
.Compare:
CRM_Utils_Crypt
, the format of********
was determined by the PECL configuration, which is usually out-of-sight/out-of-mind. Consequently, I would wager that the behavior seems unreliable/confusing to administrators -- on one deployment/server,********
is interpreted as plaintext, and it works intuitively. On another, the********
is interpreted as ciphertext, and it's very difficult to set correctly.crypto.token
, the PECL configuration is not decisive. The sysadmin can put thesmtpPassword
as plain-text ('smtpPassword' => 'mySecret'
), and that will work on any server. If they prefer to enter the override as an encrypted value, that works too ('smtpPassword' => chr(2).'CTK?k=...&t=...'
-- although I think the audience for this would be quite limited).