Ensure that the Password Change and Application Restore features comply with FIPS standards.

pull/9330/head
Khushboo Vashi 2025-11-07 17:32:51 +05:30 committed by GitHub
parent c04b9198c8
commit d1805c5640
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 8 additions and 50 deletions

View File

@ -21,7 +21,7 @@ from pgadmin.browser.server_groups.servers.types import ServerType
from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.utils import PGChildNodeView
from pgadmin.utils.ajax import make_json_response, bad_request, forbidden, \ from pgadmin.utils.ajax import make_json_response, bad_request, forbidden, \
make_response as ajax_response, internal_server_error, unauthorized, gone make_response as ajax_response, internal_server_error, unauthorized, gone
from pgadmin.utils.crypto import encrypt, decrypt, pqencryptpassword from pgadmin.utils.crypto import encrypt, decrypt
from pgadmin.utils.menu import MenuItem from pgadmin.utils.menu import MenuItem
from pgadmin.tools.sqleditor.utils.query_history import QueryHistory from pgadmin.tools.sqleditor.utils.query_history import QueryHistory
from pgadmin.tools.user_management.PgAdminPermissions import AllPermissionTypes from pgadmin.tools.user_management.PgAdminPermissions import AllPermissionTypes
@ -1881,16 +1881,11 @@ class ServerNode(PGChildNodeView):
return unauthorized(gettext("Incorrect password.")) return unauthorized(gettext("Incorrect password."))
# Hash new password before saving it. # Hash new password before saving it.
if manager.sversion >= 100000: password = conn.pq_encrypt_password_conn(data['newPassword'],
password = conn.pq_encrypt_password_conn(data['newPassword'], manager.user)
manager.user) if password is None:
if password is None: return internal_server_error(errormsg="Unable to"
# Unable to encrypt the password so used the " change the password.")
# old method of encryption
password = pqencryptpassword(data['newPassword'],
manager.user)
else:
password = pqencryptpassword(data['newPassword'], manager.user)
SQL = render_template( SQL = render_template(
"/servers/sql/#{0}#/change_password.sql".format( "/servers/sql/#{0}#/change_password.sql".format(

View File

@ -27,7 +27,6 @@ class DBPasswordChange(BaseTestGenerator):
utils.write_node_info("sid", server_dict) utils.write_node_info("sid", server_dict)
@patch('pgadmin.browser.server_groups.servers.render_template') @patch('pgadmin.browser.server_groups.servers.render_template')
@patch('pgadmin.browser.server_groups.servers.pqencryptpassword')
@patch('pgadmin.browser.server_groups.servers.decrypt') @patch('pgadmin.browser.server_groups.servers.decrypt')
@patch('pgadmin.browser.server_groups.servers.get_driver') @patch('pgadmin.browser.server_groups.servers.get_driver')
@patch('pgadmin.browser.server_groups.servers.db') @patch('pgadmin.browser.server_groups.servers.db')
@ -35,7 +34,7 @@ class DBPasswordChange(BaseTestGenerator):
@patch('pgadmin.browser.server_groups.servers.User') @patch('pgadmin.browser.server_groups.servers.User')
@patch('pgadmin.browser.server_groups.servers.current_user') @patch('pgadmin.browser.server_groups.servers.current_user')
def runTest(self, current_user_mock, user_mock, server_mock, db_mock, def runTest(self, current_user_mock, user_mock, server_mock, db_mock,
get_driver_mock, decrypt_mock, pqencryptpassword_mock, get_driver_mock, decrypt_mock,
render_template_mock): render_template_mock):
current_user_mock.id = 1 current_user_mock.id = 1
@ -54,7 +53,6 @@ class DBPasswordChange(BaseTestGenerator):
['connection_execute_scalar_return_value']) ['connection_execute_scalar_return_value'])
decrypt_mock.return_value = self.manager.password decrypt_mock.return_value = self.manager.password
pqencryptpassword_mock.return_value = self.manager.password
class TestMockServer(): class TestMockServer():
def __init__(self, name, sid, password, passfile): def __init__(self, name, sid, password, passfile):

View File

@ -513,7 +513,7 @@ def delete_tool_data(trans_id=None):
def compute_md5_hash_file(file_path, chunk_size=8192): def compute_md5_hash_file(file_path, chunk_size=8192):
"""Compute md5 hash for large files by reading in chunks.""" """Compute md5 hash for large files by reading in chunks."""
md5_hash = hashlib.md5() md5_hash = hashlib.sha256()
# Open the file in binary mode # Open the file in binary mode
with open(file_path, "rb") as file: with open(file_path, "rb") as file:

View File

@ -76,38 +76,3 @@ def pad(key):
# Add padding to make key 32 bytes long # Add padding to make key 32 bytes long
return key.ljust(32, padding_string) return key.ljust(32, padding_string)
def pqencryptpassword(password, user):
"""
pqencryptpassword -- to encrypt a password
This is intended to be used by client applications that wish to send
commands like ALTER USER joe PASSWORD 'pwd'. The password need not
be sent in cleartext if it is encrypted on the client side. This is
good because it ensures the cleartext password won't end up in logs,
pg_stat displays, etc. We export the function so that clients won't
be dependent on low-level details like whether the enceyption is MD5
or something else.
Arguments are the cleartext password, and the SQL name of the user it
is for.
Return value is "md5" followed by a 32-hex-digit MD5 checksum..
Args:
password:
user:
Returns:
"""
m = hashlib.md5()
# Place salt at the end because it may be known by users trying to crack
# the MD5 output.
m.update(password.encode())
m.update(user.encode())
return "md5" + m.hexdigest()