Skip to content

Commit 107fb09

Browse files
committed
Fix #34 KeePass: socket connection failed when used in parallel
1 parent ac84c3c commit 107fb09

File tree

2 files changed

+31
-13
lines changed

2 files changed

+31
-13
lines changed

galaxy.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace: viczem
88
name: keepass
99

1010
# The version of the collection. Must be compatible with semantic versioning
11-
version: 0.7.1
11+
version: 0.7.2
1212

1313
# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
1414
readme: README.md

plugins/lookup/keepass.py

+30-12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import argparse
44
import getpass
55
import hashlib
6+
import fcntl
67
import os
78
import re
89
import socket
@@ -21,7 +22,7 @@
2122
DOCUMENTATION = """
2223
lookup: keepass
2324
author: Victor Zemtsov <[email protected]>
24-
version_added: '0.7.1'
25+
version_added: '0.7.2'
2526
short_description: Fetching data from KeePass file
2627
description:
2728
- This lookup returns a value of a property of a KeePass entry
@@ -88,7 +89,9 @@ def run(self, terms, variables=None, **kwargs):
8889
socket_path = _keepass_socket_path(var_dbx)
8990
lock_file_ = socket_path + ".lock"
9091

91-
if not os.path.isfile(lock_file_):
92+
try:
93+
os.open(lock_file_, os.O_RDWR)
94+
except FileNotFoundError:
9295
cmd = [
9396
"/usr/bin/env",
9497
"python3",
@@ -189,7 +192,6 @@ def _keepass_socket(kdbx, kdbx_key, sock_path, ttl=60, kdbx_password=None):
189192
"""
190193
tmp_files = []
191194
try:
192-
os.umask(0o177)
193195
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
194196
s.bind(sock_path)
195197
s.listen(1)
@@ -240,6 +242,9 @@ def _keepass_socket(kdbx, kdbx_key, sock_path, ttl=60, kdbx_password=None):
240242
else:
241243
conn.send(_resp("password", 1))
242244
break
245+
elif cmd == "password":
246+
conn.send(_resp("password", 0))
247+
break
243248

244249
# CMD: fetch
245250
# Read data from decrypted KeePass file
@@ -404,6 +409,20 @@ def _keepass_socket_path(dbx_path):
404409
return "%s/ansible-keepass-%s.sock" % (tempdir, suffix[:8])
405410

406411

412+
def lock(kdbx_sock_path):
413+
fd = os.open(kdbx_sock_path + ".lock", os.O_RDWR | os.O_CREAT | os.O_TRUNC)
414+
415+
try:
416+
# The LOCK_EX means that only one process can hold the lock
417+
# The LOCK_NB means that the fcntl.flock() is not blocking
418+
# https://docs.python.org/3/library/fcntl.html#fcntl.flock
419+
fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
420+
except (IOError, OSError):
421+
return None
422+
423+
return fd
424+
425+
407426
if __name__ == "__main__":
408427
arg_parser = argparse.ArgumentParser()
409428
arg_parser.add_argument("kdbx", type=str)
@@ -413,24 +432,23 @@ def _keepass_socket_path(dbx_path):
413432
arg_parser.add_argument("--ask-pass", action="store_true")
414433
args = arg_parser.parse_args()
415434

416-
kdbx = os.path.realpath(os.path.expanduser(os.path.expandvars(args.kdbx)))
435+
arg_kdbx = os.path.realpath(os.path.expanduser(os.path.expandvars(args.kdbx)))
417436
if args.key:
418-
key = os.path.realpath(os.path.expanduser(os.path.expandvars(args.key)))
437+
arg_key = os.path.realpath(os.path.expanduser(os.path.expandvars(args.key)))
419438
else:
420-
key = None
439+
arg_key = None
421440

422441
if args.kdbx_sock:
423-
kdbx_sock = args.kdbx_sock
442+
arg_kdbx_sock = args.kdbx_sock
424443
else:
425-
kdbx_sock = _keepass_socket_path(kdbx)
444+
arg_kdbx_sock = _keepass_socket_path(arg_kdbx)
426445

427446
password = None
428447
if args.ask_pass:
429448
password = getpass.getpass("Password: ")
430449
if isinstance(password, bytes):
431450
password = password.decode(sys.stdin.encoding)
432451

433-
lock_file = kdbx_sock + ".lock"
434-
if not os.path.isfile(lock_file):
435-
open(lock_file, "a").close()
436-
_keepass_socket(kdbx, key, kdbx_sock, args.ttl, password)
452+
os.umask(0o177)
453+
if lock(arg_kdbx_sock):
454+
_keepass_socket(arg_kdbx, arg_key, arg_kdbx_sock, args.ttl, password)

0 commit comments

Comments
 (0)