Opened 8 years ago
Closed 6 years ago
#12854 closed defect (fixed)
Clicking on the Admin Users link generates "error:060800A3:digital envelope routines:EVP_DigestInit_ex:disabled for fips"
Reported by: | Owned by: | Jun Omae | |
---|---|---|---|
Priority: | high | Component: | AccountManagerPlugin |
Severity: | normal | Keywords: | fips, md5, sha1 |
Cc: | Trac Release: |
Description (last modified by )
I recently upgraded our server from EL6 to EL7, however the major change is that this system is now running in FIPS mode. When systems are running in FIPS mode, MD5 hashing is not available.
Trac works OK, except when I go to Admin - Users (https://example.com/trac/admin/accounts/users). The following error appears instead of the Users page:
Trac detected an internal error: "ValueError: error:060800A3:digital envelope routines:EVP_DigestInit_ex:disabled for fips"
Trac maintainers are addressing a similar error with notification.py by adding a configuration item allowing admins to select MD5 (default) or SHA1 for the digest algorithm. Previously, MD5 was hard coded into the python scripts.
Python Traceback
Most recent call last: File "/usr/lib/python2.7/site-packages/trac/web/main.py", line 554, in _dispatch_request File "/usr/lib/python2.7/site-packages/trac/web/main.py", line 247, in dispatch File "/usr/lib/python2.7/site-packages/trac/admin/web_ui.py", line 119, in process_request File "/usr/lib/python2.7/site-packages/acct_mgr/admin.py", line 204, in render_admin_panel File "/usr/lib/python2.7/site-packages/acct_mgr/admin.py", line 449, in _do_users File "/usr/lib/python2.7/site-packages/acct_mgr/admin.py", line 73, in fetch_user_data File "/usr/lib/python2.7/site-packages/acct_mgr/model.py", line 140, in get_user_attribute
System Information:
Trac 1.0.10 Babel 0.9.6 Genshi 0.7 (with speedups) mod_wsgi 3.4 (WSGIProcessGroup WSGIApplicationGroup %{GLOBAL}) pysqlite 2.6.0 Python 2.7.5 (default, Aug 9 2016, 05:27:46) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] setuptools 0.9.8 SQLite 3.7.17 jQuery 1.7.2 jQuery UI 1.8.21 jQuery Timepicker 1.0.1 Enabled Plugins: CKIntegration 1.1dev /usr/lib/python2.7/site-packages TracAccountManager 0.4.4 /usr/lib/python2.7/site-packages
Attachments (2)
Change History (16)
comment:1 Changed 8 years ago by
comment:2 Changed 8 years ago by
Description: | modified (diff) |
---|
comment:3 Changed 8 years ago by
Owner: | changed from Steffen Hoffmann to Ryan J Ollos |
---|---|
Status: | new → accepted |
There are 3 uses of hashlib.md5
in accountmanagerplugin/trunk/acct_mgr/model.py@15717:475,493,499#L465. I'll need to study the code to see if it's a simple matter of replacing the md5 hash method with another hash method.
comment:4 Changed 8 years ago by
I noticed that as well. Could hash type be set as a config option rather than hard coding?
comment:5 Changed 8 years ago by
The attached model.py works fine. I replaced md5
with sha1
.
Note that my trac.ini [account-manager] section also contains htpasswd_hash_type = sha1
comment:6 Changed 8 years ago by
Could you please post patch as unified diff format rather than modified file? See trac:wiki:TracDev/SubmittingPatches.
comment:7 Changed 8 years ago by
Yes, I'll work on this ASAP. Will be out of town this weekend, look for it next week. This would be my very first submitted patch to anything. :D
comment:8 Changed 8 years ago by
Owner: | Ryan J Ollos deleted |
---|---|
Status: | accepted → new |
comment:9 Changed 7 years ago by
Realized that I never attached the patch file. Just attached to this ticket.
Changed 7 years ago by
diff -Uaur ORIG_model.py NEW_model.py > patch.txt
comment:10 Changed 7 years ago by
Keywords: | algorithm Digest removed |
---|
comment:11 Changed 7 years ago by
The updated file works fine - this issue could be marked closed, or once verified perhaps rolled into production?
comment:12 Changed 6 years ago by
I noticed an issue about the hexdigest while refactoring the patch. Same hexdigest can be generated because account, authenticated and name are simply concatenated.
account | authenticated | name | concatenated string |
---|---|---|---|
foo | 1 | b0ah | foo1b0ah |
foo1b | 0 | ah | foo1b0ah |
Work around is to pad null byte between values:
-
accountmanagerplugin/trunk/acct_mgr/model.py
diff --git a/accountmanagerplugin/trunk/acct_mgr/model.py b/accountmanagerplugin/trunk/acct_mgr/model.py index 24aa7233d..8c421a77a 100644
a b def get_user_attribute(env, username=None, authenticated=1, attribute=None, 441 441 """ % (sel_stmt, where_stmt) 442 442 sql_args = tuple(constraints) 443 443 444 def unique_id(*values): 445 # Generate sha1 digest from NUL value1 NUL value2 NUL value3 NUL 446 m = hashlib.sha1() 447 m.update('\0') 448 for value in values: 449 if isinstance(value, unicode): 450 value = value.encode('utf-8') 451 elif not isinstance(value, str): 452 value = str(value) 453 m.update(value) 454 m.update('\0') 455 return m.hexdigest() 456 444 457 res = {} 445 458 for row in env.db_query(sql, sql_args): 446 459 if sel_stmt == 'COUNT(*)': … … def get_user_attribute(env, username=None, authenticated=1, attribute=None, 452 465 account = res_row.pop('sid') 453 466 authenticated = res_row.pop('authenticated') 454 467 # Create single unique attribute ID. 455 m = hashlib.md5() 456 m.update(''.join([account, str(authenticated), 457 res_row.get('name')]).encode('utf-8')) 458 row_id = m.hexdigest() 468 row_id = unique_id(account, authenticated, res_row.get('name')) 459 469 if account in res: 460 470 if authenticated in res[account]: 461 471 res[account][authenticated].update({ … … def get_user_attribute(env, username=None, authenticated=1, attribute=None, 470 480 'id': {res_row['name']: row_id} 471 481 } 472 482 # Create account ID for additional authentication state. 473 m = hashlib.md5() 474 m.update(''.join([account, 475 str(authenticated)]).encode('utf-8')) 476 res[account]['id'][authenticated] = m.hexdigest() 483 res[account]['id'][authenticated] = unique_id(account, 484 authenticated) 477 485 else: 478 486 # Create account ID for authentication state. 479 m = hashlib.md5()480 m.update(''.join([account, str(authenticated)]).encode('utf-8'))481 487 res[account] = { 482 488 authenticated: { 483 489 res_row['name']: res_row['value'], 484 490 'id': {res_row['name']: row_id} 485 491 }, 486 'id': {authenticated: m.hexdigest()}492 'id': {authenticated: unique_id(account, authenticated)} 487 493 } 488 494 return res 489 495
comment:13 Changed 6 years ago by
comment:12 change looks good to me. Please go ahead and commit that and any other changes you like.
comment:14 Changed 6 years ago by
Owner: | set to Jun Omae |
---|---|
Resolution: | → fixed |
Status: | new → closed |
In 17222:
Apologies for the formatting in the submitted bug report. I am unable to edit.