replace-backends-pass.py 2.25 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python3

"""
This script edits your backends conf file by replacing stuff like:

[bnporc21]
_module = bnporc
website = pp
login = 123456
password = 78910

with:

[bnporc21]
_module = bnporc
website = pp
login = 123456
18
password = `pass show woob/bnporc21/password`
19
20
"""

21
22
from __future__ import print_function

23
24
25
26
27
28
29
import os
import re
import shutil
import subprocess
import sys
import tempfile

30
31
SECRET_KEYWORDS = ('password', 'secret')

32
FILE = os.getenv('WOOB_BACKENDS') or os.path.expanduser('~/.config/woob/backends')
33
34
35
36
37
38
39
40
41
42
43
44

if not os.path.exists(FILE):
    print('the backends file does not exist')
    sys.exit(os.EX_NOINPUT)

if not shutil.which('pass'):
    print('the "pass" tool could not be found')
    sys.exit(os.EX_UNAVAILABLE)

errors = 0
seen = set()

45
backend = None
46
47
48
49

# building regex (^.*?keyword_1.*?|^.*?keyword_2.*?)\s*=\s*(\S.*)$
regex = r'(%s)\s*=\s*(\S.*)$' % '|'.join(['^.*?' + keyword + '.*?' for keyword in SECRET_KEYWORDS])

50
51
52
53
54
with open(FILE) as inp:
    with tempfile.NamedTemporaryFile('w', delete=False, dir=os.path.dirname(FILE)) as outp:
        for line in inp:
            line = line.strip()

55
56
            mtc = re.match(regex, line)
            if mtc and not mtc.group(2).startswith('`'):
57
                cmd = ['pass', 'insert', 'woob/%s/%s' % (backend, mtc.group(1))]
58
                stdin = 2 * ('%s\n' % mtc.group(2))
59
60
61
                proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
                proc.communicate(stdin.encode('utf-8'))
                if proc.returncode == 0:
62
                    print('%s = `pass show woob/%s/%s`' % (mtc.group(1), backend, mtc.group(1)), file=outp)
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
                    continue
                else:
                    errors += 1
                    print('warning: could not store password for backend %r' % backend)

            mtc = re.match(r'\[(.+)\]', line)
            if mtc:
                backend = mtc.group(1)
                if backend in seen:
                    print('error: backend %r is present multiple times' % backend)
                    sys.exit(os.EX_DATAERR)
                seen.add(backend)

            print(line, file=outp)

os.rename(outp.name, FILE)

if errors:
    print('%d errors were encountered when storing passwords securely' % errors)
    sys.exit(2)