Merge bootstack-ops:rm-juju-bundle-export-mask into bootstack-ops:master

Proposed by Joe Guo
Status: Merged
Approved by: Xav Paice
Approved revision: a9fbfa0baba7e300f4da7d38ff67b1f07fa7f743
Merged at revision: 2c6ef760296a91c213a3ff60c1a445a1cd952868
Proposed branch: bootstack-ops:rm-juju-bundle-export-mask
Merge into: bootstack-ops:master
Diff against target: 132 lines (+0/-126)
1 file modified
dev/null (+0/-126)
Reviewer Review Type Date Requested Status
Xav Paice (community) Approve
Review via email: mp+384086@code.launchpad.net

Commit message

juju-bundle-export-mask.py: rm redundant script

This script seems to be an older version of `juju_export_bundle.py`.
remove it to avoid confusing.

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Xav Paice (xavpaice) wrote :

+1 let's keep things simple

review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 2c6ef760296a91c213a3ff60c1a445a1cd952868

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/bootstack-ops/juju-bundle-export-mask.py b/bootstack-ops/juju-bundle-export-mask.py
0deleted file mode 1007550deleted file mode 100755
index 0df53e1..0000000
--- a/bootstack-ops/juju-bundle-export-mask.py
+++ /dev/null
@@ -1,126 +0,0 @@
1#!/usr/bin/env python
2
3from __future__ import print_function
4import re
5import sys
6import yaml
7import argparse
8import math
9
10
11MASK_KEYS = '(.*(ssl-public-key|ssl[_-](ca|cert|key)|secret|password|pagerduty_key|license-file|registration-key|token|accesskey|private-ppa|(http|https)://.*:.+\@|os-credentials).*)|key'
12
13
14def readbundle(filename):
15 try:
16 mybundle = yaml.load(filename.read())
17 except yaml.YAMLError as exc:
18 print(exc)
19
20 return mybundle
21
22
23def mask_keys_in_dict(mydict, mask, level='ROOT'):
24 for k, v in mydict.iteritems():
25 if isinstance(v, dict):
26 mask_keys_in_dict(v, mask, level=('{}:{}'.format(level, k)))
27 else:
28 result = mask.match(k)
29 if result is not None:
30 mydict[k] = 'THIS_VALUE_IS_MASKED_FOR_SECURITY'
31 elif type(v) in (str,):
32 result = mask.match(v)
33 if result is not None:
34 print('WARNING! Masked keyword "{}" found in value for {}'.format(result.groups()[1], level))
35 print('Check output file, may not be secure.')
36 print()
37 if v == 'truetrue':
38 mydict[k] = 'true'
39 elif v == 'falsetrue':
40 mydict[k] = 'false'
41
42
43def parse_args():
44 parser = argparse.ArgumentParser(
45 description='Mask juju bundle export file secrets')
46 parser.add_argument('-i', dest='infile', nargs='?',
47 type=argparse.FileType('r'), default=sys.stdin)
48 parser.add_argument('-o', dest='outfile', nargs='?',
49 type=argparse.FileType('w'), default=sys.stdout)
50
51 result = parser.parse_args(sys.argv[1:])
52 return result
53
54
55def shannon_entropy(data, iterator):
56 """
57 Borrowed from http://blog.dkbza.org/2007/05/scanning-data-for-entropy-anomalies.html
58 """
59 if not data:
60 return 0
61 entropy = 0
62 for x in iterator:
63 p_x = float(data.count(x)) / len(data)
64 if p_x > 0:
65 entropy += - p_x * math.log(p_x, 2)
66 return entropy
67
68
69def get_strings_of_set(word, char_set, threshold=8):
70 count = 0
71 letters = ""
72 strings = []
73 for char in word:
74 if char in char_set:
75 letters += char
76 count += 1
77 else:
78 if count > threshold:
79 strings.append(letters)
80 letters = ""
81 count = 0
82 if count > threshold:
83 strings.append(letters)
84 return strings
85
86
87def check_for_entropy_in_dict(bundle):
88 lines = yaml.dump(bundle).split('\n')
89 stringsFound = []
90 entropy_found = False
91 BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
92 HEX_CHARS = "1234567890abcdefABCDEF"
93 for line in lines:
94 for word in line.split():
95 base64_strings = get_strings_of_set(word, BASE64_CHARS)
96 hex_strings = get_strings_of_set(word, HEX_CHARS)
97 for string in base64_strings:
98 b64Entropy = shannon_entropy(string, BASE64_CHARS)
99 if b64Entropy > 3.8:
100 stringsFound.append(string)
101 entropy_found = True
102 print('WARNING! Entropy found in string "{}"'.format(string))
103 for string in hex_strings:
104 hexEntropy = shannon_entropy(string, HEX_CHARS)
105 if hexEntropy > 3:
106 stringsFound.append(string)
107 entropy_found = True
108 print('WARNING! Entropy found in string "{}"'.format(string))
109
110 if len(stringsFound) != 0:
111 print('ERROR!!! Check output file for entropy warnings, may not be secure.')
112
113 return entropy_found
114
115
116def main():
117 args = parse_args()
118 bundle = readbundle(args.infile)
119 mask_regex = re.compile(MASK_KEYS)
120 mask_keys_in_dict(bundle, mask_regex)
121 check_for_entropy_in_dict(bundle)
122 print(yaml.dump(bundle, default_flow_style=False), file=args.outfile)
123
124
125if __name__ == "__main__":
126 main()

Subscribers

People subscribed via source and target branches

to all changes: