Ensure that the Password Change and Application Restore features comply with FIPS standards.
parent
c04b9198c8
commit
d1805c5640
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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()
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue