Skip to content

Commit d2fd81e

Browse files
mgr/dashboard: replace direct use of bcrypt in dashboard
Replace a direct usage of bycrypt with our cryptocaller wrapper. Signed-off-by: John Mulligan <jmulligan@redhat.com>
1 parent 5d4eeff commit d2fd81e

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

src/pybind/mgr/dashboard/services/access_control.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from string import ascii_lowercase, ascii_uppercase, digits, punctuation
1313
from typing import List, Optional, Sequence
1414

15-
import bcrypt
1615
from mgr_module import CLICheckNonemptyFileInput, CLIReadCommand, CLIWriteCommand
1716
from mgr_util import password_hash
1817

@@ -24,6 +23,8 @@
2423
from ..security import Permission, Scope
2524
from ..settings import Settings
2625

26+
import ceph.cryptotools.remote
27+
2728
logger = logging.getLogger('access_control')
2829
DEFAULT_FILE_DESC = 'password/secret'
2930

@@ -929,7 +930,10 @@ def ac_user_set_password_hash(_, username: str, inbuf: str):
929930
hashed_password = inbuf
930931
try:
931932
# make sure the hashed_password is actually a bcrypt hash
932-
bcrypt.checkpw(b'', hashed_password.encode('utf-8'))
933+
# catch a ValueError if hashed_password is not valid.
934+
cc = ceph.cryptotools.remote.CryptoCaller()
935+
cc.verify_password('', hashed_password)
936+
933937
user = mgr.ACCESS_CTRL_DB.get_user(username)
934938
user.set_password_hash(hashed_password)
935939

src/python-common/ceph/cryptotools/cryptotools.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ def password_hash(args: Namespace) -> None:
3333
json.dump({'hash': hash_str}, sys.stdout)
3434

3535

36+
def verify_password(args: Namespace) -> None:
37+
data = json.loads(sys.stdin.read())
38+
password = data.encode('utf-8')
39+
hashed_password = data.encode('utf-8')
40+
try:
41+
ok = bcrypt.checkpw(password, hashed_password)
42+
except ValueError as err:
43+
_fail_message(str(err))
44+
json.dump({'ok': ok}, sys.stdout)
45+
46+
3647
def create_self_signed_cert(args: Namespace) -> None:
3748

3849
# Generate private key
@@ -192,6 +203,10 @@ def verify_tls(args: Namespace) -> None:
192203
parser_verify_tls = subparsers.add_parser('verify_tls')
193204
parser_verify_tls.set_defaults(func=verify_tls)
194205

206+
# password verification
207+
parser_verify_password = subparsers.add_parser('verify_password')
208+
parser_verify_password.set_defaults(func=verify_password)
209+
195210
# parse the args and call whatever function was selected
196211
args = parser.parse_args()
197212
args.func(args)

src/python-common/ceph/cryptotools/remote.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,18 @@ def password_hash(self, password: str, salt_password: str) -> str:
167167
if not pw_hash:
168168
raise CryptoCallError('no password hash')
169169
return pw_hash
170+
171+
def verify_password(self, password: str, hashed_password: str) -> bool:
172+
"""Verify a password matches the hashed password. Returns true if
173+
password and hashed_password match.
174+
"""
175+
pwdata = {"password": password, "hashed_password": hashed_password}
176+
result = self._run(
177+
["verify_password"],
178+
input_data=json.dumps(pwdata),
179+
capture_output=True,
180+
check=True,
181+
)
182+
result_obj = self._result_json(result)
183+
ok = result_obj.get("ok", False)
184+
return ok

0 commit comments

Comments
 (0)