Skip to content
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

[4.0.7] regression -> gnome secrets crashes on expiration date check with missmatch of date format #382

Closed
fabiscafe opened this issue Mar 9, 2024 · 7 comments · Fixed by #383

Comments

@fabiscafe
Copy link

fabiscafe commented Mar 9, 2024

  • System: Arch Linux
  • python 3.11.8
  • pykeepass 4.0.7
  • secrets 8.0

Secrets is a password manager.

After importing #378 to make secrets even build and work (see the PR), secrets now crashes when trying to unlock the .kdbx. It looks like at least one of my expiration dates does have an incompatible format. This shouldn't happen inside a minor release. Rolling back to pykeepass 4.0.6 makes secrets work again.

This is the output I get when starting it from the terminal.

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/gsecrets/unlock_database.py", line 212, in _unlock_callback
    database_manager.unlock_finish(result)
  File "/usr/lib/python3.11/site-packages/gsecrets/database_manager.py", line 124, in unlock_finish
    self.entries.splice(0, 0, [SafeEntry(self, e) for e in db.entries])
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/gsecrets/database_manager.py", line 124, in <listcomp>
    self.entries.splice(0, 0, [SafeEntry(self, e) for e in db.entries])
                               ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/gsecrets/safe_element.py", line 545, in __init__
    self._check_expiration()
  File "/usr/lib/python3.11/site-packages/gsecrets/safe_element.py", line 603, in _check_expiration
    if self.props.expired:
       ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/gi/_propertyhelper.py", line 394, in obj_get_property
    return getattr(self, name, None)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/gi/_propertyhelper.py", line 207, in __get__
    value = self.fget(instance)
            ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/gsecrets/safe_element.py", line 919, in expired
    return self.entry.expired
           ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pykeepass/baseelement.py", line 120, in expired
    self.expiry_time
  File "/usr/lib/python3.11/site-packages/pykeepass/baseelement.py", line 127, in expiry_time
    return self._get_times_property('ExpiryTime')
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pykeepass/baseelement.py", line 94, in _get_times_property
    return self._kp._decode_time(prop.text)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pykeepass/pykeepass.py", line 824, in _decode_time
    return datetime.strptime(text, DT_ISOFORMAT).replace(tzinfo=timezone.utc)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/_strptime.py", line 567, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/_strptime.py", line 349, in _strptime
    raise ValueError("time data %r does not match format %r" %
ValueError: time data '2024-01-29T23:00:00+00:00' does not match format '%Y-%m-%dT%H:%M:%S%fZ'
@fabiscafe fabiscafe changed the title [4.0.7] regression -> gnome secrets crashes on startup. [4.0.7] regression -> gnome secrets crashes on file unlock. Mar 9, 2024
@fabiscafe fabiscafe changed the title [4.0.7] regression -> gnome secrets crashes on file unlock. [4.0.7] regression -> gnome secrets crashes on expiration date check with missmatch of date format Mar 9, 2024
@fabiscafe
Copy link
Author

This might be related to a2da685

However this can't be reverted on top of current stable.

@City-busz
Copy link
Contributor

A simple fix could be to replace +00:00 with Z on line 824:
return datetime.strptime(text.replace('+00:00','Z'), DT_ISOFORMAT).replace(tzinfo=timezone.utc)

@City-busz
Copy link
Contributor

Or maybe just replace the Z parameter with %z on line 31:
DT_ISOFORMAT = "%Y-%m-%dT%H:%M:%S%f%z"

@fabiscafe
Copy link
Author

DT_ISOFORMAT = "%Y-%m-%dT%H:%M:%S%f%z"

@City-busz This works for one case, thanks. But I just hit on another one.

% secrets
Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/gi/overrides/__init__.py", line 351, in wrap
    return func(a, b, *user_data)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/gsecrets/sorting.py", line 48, in sort_by_ctime_asc
    if ele1.ctime is None or ele2.ctime is None:
       ^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/gsecrets/safe_element.py", line 328, in ctime
    time = self._element.ctime
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pykeepass/baseelement.py", line 136, in ctime
    return self._get_times_property('CreationTime')
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pykeepass/baseelement.py", line 94, in _get_times_property
    return self._kp._decode_time(prop.text)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pykeepass/pykeepass.py", line 824, in _decode_time
    return datetime.strptime(text, DT_ISOFORMAT).replace(tzinfo=timezone.utc)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/_strptime.py", line 567, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/_strptime.py", line 349, in _strptime
    raise ValueError("time data %r does not match format %r" %
ValueError: time data '2019-02-22T15:04:26.027609+00:00' does not match format '%Y-%m-%dT%H:%M:%S%f%z'

So far I have

  • '2018-01-25T14:23:05Z' (Thats the one from the tests)
  • '2024-01-29T23:00:00+00:00'
  • '2019-02-22T15:04:26.027609+00:00'

@City-busz
Copy link
Contributor

Ah, just replace the line 824 with:
return datetime.fromisoformat(text).replace(tzinfo=timezone.utc)

It should work in all cases. :)

City-busz added a commit to City-busz/pykeepass that referenced this issue Mar 10, 2024
The ISO formatted string can be stored in multiple formats. Use the built-in datetime.isoformat() and datetime.fromisoformat() functions, which able to handle all variants.

Fixes: libkeepass#382
@City-busz
Copy link
Contributor

I submitted #383, which should fix this problem.

@fabiscafe
Copy link
Author

LGTM - With #383 I can open, edit and save both of my files 👍

City-busz added a commit to City-busz/pykeepass that referenced this issue Mar 11, 2024
The ISO formatted string can be stored in multiple formats. Use the built-in datetime.isoformat() and datetime.fromisoformat() functions, which able to handle all variants.
Replace 'Z' with '+00:00' to ensure compatibility with Python < 3.11.

Fixes: libkeepass#382
Evidlo pushed a commit that referenced this issue Mar 11, 2024
The ISO formatted string can be stored in multiple formats. Use the built-in datetime.isoformat() and datetime.fromisoformat() functions, which able to handle all variants.
Replace 'Z' with '+00:00' to ensure compatibility with Python < 3.11.

Fixes: #382
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 a pull request may close this issue.

2 participants