opensecret 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/README.md +2 -2
- data/bin/opensecret +3 -6
- data/lib/opensecret-domain.ini +23 -0
- data/lib/opensecret.rb +30 -2
- data/lib/opensecret/additions/array.rb +117 -0
- data/lib/opensecret/additions/dir.rb +35 -0
- data/lib/opensecret/additions/string.rb +312 -0
- data/lib/opensecret/commons/eco.cmdline.rb +446 -0
- data/lib/opensecret/commons/eco.faculty.rb +364 -0
- data/lib/opensecret/commons/eco.system.rb +437 -0
- data/lib/opensecret/commons/eco.systems.rb +98 -0
- data/lib/opensecret/{safe.rb → delegate.rb} +4 -2
- data/lib/opensecret/eco.do.rb +46 -0
- data/lib/opensecret/executors/crypt.keys/crypt.keys.ini +79 -0
- data/lib/opensecret/executors/crypt.keys/crypt.keys.rb +68 -0
- data/lib/opensecret/executors/decrypt/decrypt.ini +64 -0
- data/lib/opensecret/executors/decrypt/decrypt.rb +49 -0
- data/lib/opensecret/executors/encrypt/encrypt.ini +55 -0
- data/lib/opensecret/executors/encrypt/encrypt.rb +82 -0
- data/lib/opensecret/factbase/hub-runtime.ini +123 -0
- data/lib/opensecret/factbase/known-hosts.ini +75 -0
- data/lib/opensecret/factbase/published.facts/blobbolicious-facts.ini +553 -0
- data/lib/opensecret/factbase/published.facts/credential-facts.ini +40 -0
- data/lib/opensecret/factbase/published.facts/infrastructure-facts.ini +63 -0
- data/lib/opensecret/factbase/readme.md +24 -0
- data/lib/opensecret/factbase/retired.facts/maven.database.ide.facts.ini +127 -0
- data/lib/opensecret/factbase/retired.facts/s3-upload-block-facts.ini +17 -0
- data/lib/opensecret/plugins.io/cipher/crypto.rb +174 -0
- data/lib/opensecret/plugins.io/error/eco.exceptions.rb +24 -0
- data/lib/opensecret/plugins.io/facts/fact.chars.rb +66 -0
- data/lib/opensecret/plugins.io/facts/fact.factor.rb +156 -0
- data/lib/opensecret/plugins.io/facts/fact.locator.rb +105 -0
- data/lib/opensecret/plugins.io/facts/fact.reader.rb +137 -0
- data/lib/opensecret/plugins.io/facts/fact.tree.rb +661 -0
- data/lib/opensecret/plugins.io/file/file.rb +483 -0
- data/lib/opensecret/plugins.io/git/git.flow.rb +388 -0
- data/lib/opensecret/plugins.io/logs/log.object.rb +89 -0
- data/lib/opensecret/plugins.io/logs/logging.rb +203 -0
- data/lib/opensecret/plugins.io/time/time.stamp.rb +425 -0
- data/lib/opensecret/version.rb +2 -2
- data/opensecret.gemspec +8 -13
- metadata +68 -18
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
# --
|
3
|
+
# -- If a plugin requires AWS IAM user credentials you must
|
4
|
+
# -- define the directory the credentials are in within the
|
5
|
+
# -- [plugin+platform] fact file.
|
6
|
+
# --
|
7
|
+
# -- A credentials INI factfile is expected to exist within
|
8
|
+
# -- that directory with the name
|
9
|
+
# --
|
10
|
+
# -- => [:eco][id] + ".aws.credentials.ini"
|
11
|
+
# -- => ci.hub.aws.credentials.ini [(if id is ci.hub)]
|
12
|
+
# --
|
13
|
+
# -- To specify AWS IAM credentials for a plugin, you
|
14
|
+
# --
|
15
|
+
# -- [1] specify [:aws][:keys_folder] in [plugin+platform]
|
16
|
+
# -- [2] put <<eco.id>>.aws.credentials.ini inside folder
|
17
|
+
# --
|
18
|
+
# -- The format of the credentials file for a plugin ID of
|
19
|
+
# -- (ci.hub) named [ci.hub.aws.credentials.ini] would be
|
20
|
+
# --
|
21
|
+
# -- [ci.hub]
|
22
|
+
# -- aws.access.key = AKIA12345
|
23
|
+
# -- aws.secret.key = abc123secret
|
24
|
+
# -- aws.region.key = us-east-2
|
25
|
+
# --
|
26
|
+
# -- ----------------------------
|
27
|
+
# -- AWS Credentials | Summary
|
28
|
+
# -- ----------------------------
|
29
|
+
# --
|
30
|
+
# -- [One] plugin running on [a] workstation or inside [a]
|
31
|
+
# -- container can only use [one] set of IAM user credentials
|
32
|
+
# -- located in [an] accessible folder (on a removable drive).
|
33
|
+
# --
|
34
|
+
|
35
|
+
[aws]
|
36
|
+
creds.name = e>> @f[:eco][:id] + Do.t + "aws.credentials.ini"
|
37
|
+
dir.exists? = e>> !@f[@i[:workstation]][:aws_creds_dir].nil?
|
38
|
+
creds.path(if) = { @s[:dir_exists?] } e>> File.join @f[@i[:workstation]][:aws_creds_dir], @s[:creds_name]
|
39
|
+
creds.exist? = e>> exists?(@s[:creds_path]) && File.exists?(@s[:creds_path])
|
40
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
[terraform]
|
3
|
+
aws.instance.id = e>> "ec2-" + @f[:stamp][:mini_2]
|
4
|
+
aws.sgroup.id = e>> "acl-" + @f[:stamp][:mini_2]
|
5
|
+
route53.dns.id = e>> "dns-" + @f[:stamp][:mini_2]
|
6
|
+
route53.www.id = e>> "www-" + @f[:stamp][:mini_2]
|
7
|
+
route53.ssl.id = e>> "ssl-" + @f[:stamp][:mini_2]
|
8
|
+
resource.group = e>> @f[:stamp][:midi]
|
9
|
+
|
10
|
+
ec2.acl.name = e>> "acl." + @f[:stamp][:midi]
|
11
|
+
ec2.tag.name = e>> "ec2." + @f[:stamp][:midi]
|
12
|
+
ebs.tag.name = e>> "ebs." + @f[:stamp][:midi]
|
13
|
+
ec2.acl.desc = e>> "Rules (acl) for the " + @f[:stamp][:midi] + " tcp/ip traffic."
|
14
|
+
|
15
|
+
username = ubuntu
|
16
|
+
keypair.name = e>> "keypair." + @f[:stamp][:midi]
|
17
|
+
private.key = e>> File.join @f[:runtime][:dir], ( @s[:keypair_name] + ".pem" )
|
18
|
+
|
19
|
+
aws.exe.win = windows_amd64/terraform-provider-aws_v1.7.0_x4.exe
|
20
|
+
aws.exe.linux = linux_amd64/terraform-provider-aws_v1.6.0_x4
|
21
|
+
|
22
|
+
exe.filename(if)= { Gem.win_platform? } e>> @s[:aws_exe_win]
|
23
|
+
exe.filename(un)= { Gem.win_platform? } e>> @s[:aws_exe_linux]
|
24
|
+
exe.source.dir = e>> File.join @f[:runtime][:dir], ".terraform/plugins"
|
25
|
+
|
26
|
+
ec2.host = e>> LinuxHost.ec2_using_terraform( \
|
27
|
+
@s[:username], \
|
28
|
+
@s[:private_key], \
|
29
|
+
@f[:runtime][:dir], \
|
30
|
+
@s[:keypair_name], \
|
31
|
+
@s[:exe_filename], \
|
32
|
+
@s[:exe_source_dir], \
|
33
|
+
@f[:runtime][:archive] \
|
34
|
+
)
|
35
|
+
|
36
|
+
|
37
|
+
[domain]
|
38
|
+
has.domain? = e>> exists?( @p[:root_domain] )
|
39
|
+
root(if) = { @s[:has_domain?] } e>> @p[:root_domain]
|
40
|
+
www(if) = { @s[:has_domain?] } e>> "www" + dot + @s[:root]
|
41
|
+
https(if) = { @s[:has_domain?] } e>> "https://" + @s[:www]
|
42
|
+
http(if) = { @s[:has_domain?] } e>> "http://" + @s[:www]
|
43
|
+
|
44
|
+
|
45
|
+
[machine]
|
46
|
+
suffix = host
|
47
|
+
name.known? = e>> exists?(@f[@i[:workstation]][plugin_symbol(@s[:suffix])])
|
48
|
+
|
49
|
+
fact.name(if) = { @s[:name_known?] } e>> @f[@i[:workstation]][plugin_symbol(@s[:suffix])]
|
50
|
+
key.name(if) = { @s[:name_known?] } e>> @s[:fact_name] + ".ssh.key.pem"
|
51
|
+
ssh.key(if) = { @s[:name_known?] } e>> File.join @f[@i[:workstation]][:ssh_keydir], @s[:key_name]
|
52
|
+
user.name(if) = { @s[:name_known?] } e>> @f[symbol(@s[:fact_name])][:username]
|
53
|
+
host.name(if) = { @s[:name_known?] } e>> @f[symbol(@s[:fact_name])][:hostnames].first
|
54
|
+
net.bridge(if) = { @s[:name_known?] } e>> @f[symbol(@s[:fact_name])][:net_bridge]
|
55
|
+
|
56
|
+
host.class(if) = { @s[:name_known?] } e>> LinuxHost.existing_host( \
|
57
|
+
@s[:host_name], \
|
58
|
+
@s[:user_name], \
|
59
|
+
@s[:ssh_key], \
|
60
|
+
@s[:net_bridge] \
|
61
|
+
)
|
62
|
+
|
63
|
+
host.class(un) = { @s[:name_known?] } e>> @f[:terraform][:ec2_host]
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
# Fact File Read Order
|
3
|
+
|
4
|
+
Fact files are assimilated in a simple yet powerful manner.
|
5
|
+
|
6
|
+
## Assimilation Order
|
7
|
+
|
8
|
+
The fact files are assimilated in this order
|
9
|
+
|
10
|
+
- first the **core fact files** in the **reusable.facts** folder
|
11
|
+
- next is the **plugin's fact file** eg ***gitlab.dev.ini*** in reusable.plugins/gitlab.dev
|
12
|
+
- then every fact file in the **reusable.facts/general** directory and subdirectories
|
13
|
+
- then it is all the fact files declared for **import via HTTP, SCP, SFTP and Rest APIs**
|
14
|
+
- then from **git repositories, key-value stores** (etcd, redis) and **(nosql) databases**
|
15
|
+
- finally, **credential fact files on removable media**, in vaults and key pass structures
|
16
|
+
|
17
|
+
## Indexing for Large Fact Repositories
|
18
|
+
|
19
|
+
Once the third reusable.facts/general store becomes **large** we could devise methods of
|
20
|
+
|
21
|
+
- **indexing** all the **long-lived facts** as and when they are produced
|
22
|
+
- **mining fact dependencies** from plugin software, fact files and templates
|
23
|
+
- then **importing** just the needful set of facts (and their dependencies)
|
24
|
+
|
@@ -0,0 +1,127 @@
|
|
1
|
+
[database]
|
2
|
+
name = app_datastore
|
3
|
+
admin.username = e>> "admin.usr." + Stamp.yyjjj_hhmm_sst
|
4
|
+
admin.password = e>> Secrets.derive_alphanum
|
5
|
+
app.username = e>> "app.usr." + Stamp.yyjjj_hhmm_sst
|
6
|
+
app.password = e>> Secrets.derive_alphanum
|
7
|
+
|
8
|
+
content.url = https://www.eco-platform.co.uk/content/database.git/
|
9
|
+
content.name = e>> "db.content." + Stamp.yyjjj_hhmm_sst
|
10
|
+
content.zip = e>> @f[:database][:content_name] + ".zip"
|
11
|
+
content.files = e>> GitFlow.file_names @f[:database][:content_url]
|
12
|
+
content.path = /var/lib/mongodb/content.library
|
13
|
+
|
14
|
+
import.stmts = e>> MongoFlow.to_inport_stmts( \
|
15
|
+
@f[:database][:content_files], \
|
16
|
+
@f[:database][:content_path], \
|
17
|
+
@f[:database][:database_name], \
|
18
|
+
@f[:database][:app_username], \
|
19
|
+
@f[:database][:app_password] \
|
20
|
+
)
|
21
|
+
|
22
|
+
|
23
|
+
[rest]
|
24
|
+
docs.url = https://www.eco-platform.co.uk/content/rest.documents.git/
|
25
|
+
docs.offset = application.objects/
|
26
|
+
zip.basename = e>> @f[:s3][:upload_prefix] + "application.objects"
|
27
|
+
zip.filename = e>> @f[:rest][:zip_basename] + ".zip"
|
28
|
+
|
29
|
+
|
30
|
+
[ide]
|
31
|
+
idea.iml.dir = e>> File.join @f[:runtime][:dir], "idea_modules"
|
32
|
+
conf.repo.url = https://www.eco-platform.co.uk/content/intellij.conf.git/
|
33
|
+
conf.base.dir = e>> File.join @f[:runtime][:dir], "ide_config"
|
34
|
+
conf.dir.name = apollo.laundry4j
|
35
|
+
conf.home.dir = e>> File.join @f[:ide][:conf_base_dir], @f[:ide][:conf_dir_name]
|
36
|
+
|
37
|
+
idea.prop.src = e>> File.join @f[:runtime][:dir], "asset.idea.properties"
|
38
|
+
idea.prop.dir = C:/Program Files (x86)/JetBrains/IntelliJ IDEA Community Edition 14.0.2/bin
|
39
|
+
idea.prop.dst = e>> File.join @f[:ide][:idea_prop_dir], "idea.properties"
|
40
|
+
|
41
|
+
options.base.dir = e>> File.join @f[:runtime][:dir], "ide_config/apollo.laundry4j/options"
|
42
|
+
default.xml.file = project.default.xml
|
43
|
+
default.xml.path = e>> File.join @f[:ide][:options_base_dir], @f[:ide][:default_xml_file]
|
44
|
+
|
45
|
+
|
46
|
+
[maven]
|
47
|
+
jar.projects = e>> %w[ \
|
48
|
+
https://www.eco-platform.co.uk/commons/laundry4j.facility \
|
49
|
+
https://www.eco-platform.co.uk/commons/laundry4j.mappable \
|
50
|
+
https://www.eco-platform.co.uk/commons/laundry4j.mappers \
|
51
|
+
https://www.eco-platform.co.uk/commons/laundry4j.clusters \
|
52
|
+
https://www.eco-platform.co.uk/football/footb4ll.net \
|
53
|
+
https://www.eco-platform.co.uk/commons/laundry4j.explorer \
|
54
|
+
]
|
55
|
+
|
56
|
+
|
57
|
+
install.dir = C:/Program Files/apache-maven-3.3.9
|
58
|
+
settings.xml = C:/Program Files/apache-maven-3.3.9/conf/settings.xml
|
59
|
+
version.dev = e>> Stamp.yyjjj_hhmm_sst + "-SNAPSHOT"
|
60
|
+
version.push = e>> Stamp.yyjjj_hhmm_sst
|
61
|
+
|
62
|
+
builds.dir = e>> File.join @f[:runtime][:dir], "maven_builds"
|
63
|
+
amalgam.dir = e>> File.join @f[:runtime][:dir], "maven_projects"
|
64
|
+
javadocs.dir = e>> File.join @f[:runtime][:dir], "maven_javadocs"
|
65
|
+
apidocs.dir = e>> File.join @f[:maven][:javadocs_dir], "site/apidocs"
|
66
|
+
pom.xml.src = e>> File.join @f[:runtime][:dir], "asset.amalgam.pom.xml"
|
67
|
+
pom.xml.dst = e>> File.join @f[:maven][:amalgam_dir], "pom.xml"
|
68
|
+
|
69
|
+
css.file.src = e>> File.join @f[:runtime][:dir], "asset.stylesheet.css"
|
70
|
+
css.file.dst = e>> File.join @f[:maven][:apidocs_dir], "stylesheet.css"
|
71
|
+
|
72
|
+
index.html.src = e>> File.join @f[:maven][:apidocs_dir], "overview-summary.html"
|
73
|
+
index.html.dst = e>> File.join @f[:maven][:apidocs_dir], "index.html"
|
74
|
+
|
75
|
+
cmd.prefix = e>> "mvn -f " + @f[:maven][:pom_xml_dst] + " clean "
|
76
|
+
cmd.javadocs = e>> @f[:maven][:cmd_prefix] + "javadoc:aggregate source:aggregate"
|
77
|
+
|
78
|
+
war.project = https://www.eco-platform.co.uk/commons/laundry4j.web
|
79
|
+
war.module = e>> Pom.get_module_name @f[:maven][:war_project]
|
80
|
+
projects = e>> @f[:maven][:jar_projects].push @f[:maven][:war_project]
|
81
|
+
war.prj.dir = e>> File.join @f[:maven][:amalgam_dir], @f[:maven][:war_module]
|
82
|
+
war.pom.xml = e>> File.join @f[:maven][:war_prj_dir], "pom.xml"
|
83
|
+
war.run.cmd = e>> "mvn -f " + @f[:maven][:war_pom_xml] + " cargo:run -P tomcat8x"
|
84
|
+
|
85
|
+
module.names = e>> Pom.get_module_names @f[:maven][:projects]
|
86
|
+
module.lines = e>> Refactor.sandwich_lines @f[:maven][:module_names], "<module>", "</module>", 16
|
87
|
+
|
88
|
+
no1.prj.dir = e>> File.join @f[:maven][:amalgam_dir], @f[:maven][:module_names].first
|
89
|
+
no1.pom.xml = e>> File.join @f[:maven][:no1_prj_dir], "pom.xml"
|
90
|
+
version.cmd = e>> "mvn -f " + @f[:maven][:no1_pom_xml] + " versions:set -DgroupId=com.* -DartifactId=* -DnewVersion=" + @f[:maven][:version_dev] + " -DgenerateBackupPoms=false"
|
91
|
+
|
92
|
+
|
93
|
+
############ mvn -f facility/pom.xml versions:set -DgroupId=com.* -DartifactId=* -DnewVersion=77.77.00-SNAPSHOT
|
94
|
+
###### http://localhost:8899/explorer-17.263.1858-SNAPSHOT
|
95
|
+
|
96
|
+
# --
|
97
|
+
# -- Create ruby/maven commands that act on one or more projects
|
98
|
+
# -- Command examples
|
99
|
+
# -- - system "mvn -f maven_projects/customer/pom.xml clean install"
|
100
|
+
# --
|
101
|
+
install.opts = clean install
|
102
|
+
install.cmd = e>> "mvn -f " + @f[:maven][:pom_xml_dst] + " clean install"
|
103
|
+
|
104
|
+
## cmd.prefix = e>> "system " + Ch.dq + "mvn -f maven_projects/"
|
105
|
+
## cmd.postfix = /pom.xml
|
106
|
+
|
107
|
+
|
108
|
+
[git]
|
109
|
+
base.url = https://www.eco-platform.co.uk
|
110
|
+
local.dir = e>> File.dirname Dir.pwd
|
111
|
+
dot.git.dir = e>> File.join @f[:git][:local_dir], ".git"
|
112
|
+
revision = e>> GitFlow.wc_revision @f[:git][:dot_git_dir]
|
113
|
+
ssh.keyfile = e>> File.join Home.dir, "com.laundry4j.drive/library.ssh.access.keys/gitlab.laundry4j.private.key.pem"
|
114
|
+
|
115
|
+
[git.content]
|
116
|
+
url = e>> File.join @f[:git][:base_url], "content"
|
117
|
+
|
118
|
+
|
119
|
+
[git.commons]
|
120
|
+
url = e>> File.join @f[:git][:base_url], "commons"
|
121
|
+
eco.proj.name = eco-platform
|
122
|
+
eco.repo.name = e>> @s[:eco_proj_name] + ".git"
|
123
|
+
eco.repo.url = e>> File.join @s[:url], @s[:eco_repo_name]
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# --- --------------------------------------------------------------------- --- #
|
2
|
+
# --- This fact (INI) file database carries facts for the s3 upload block. --- #
|
3
|
+
# --- --------------------------------------------------------------------- --- #
|
4
|
+
# --- [DEPENDENCY] => @f[:upload][:src_file_name] --- #
|
5
|
+
# --- => This dependency must be set before fact evaluation. --- #
|
6
|
+
# --- --------------------------------------------------------------------- --- #
|
7
|
+
|
8
|
+
[upload]
|
9
|
+
src.file.path = e>> File.join @f[:runtime][:dir], @f[:upload][:src_file_name]
|
10
|
+
dot.full.extn = e>> File.extname @f[:upload][:src_file_path]
|
11
|
+
src.base.name = e>> File.basename @f[:upload][:src_file_name], @f[:upload][:dot_full_extn]
|
12
|
+
prefix.less.name = e>> @f[:upload][:src_base_name][ @f[:s3][:upload_prefix].length .. -1 ]
|
13
|
+
app.props.base = e>> @f[:upload][:prefix_less_name] + @f[:upload][:dot_full_extn]
|
14
|
+
app.props.key = e>> (@f[:upload][:app_props_base] + Ch.p + "url").gsub(".","_").to_sym
|
15
|
+
dst.file.base = e>> @f[:upload][:prefix_less_name] + Ch.p + @f[:stamp][:midi]
|
16
|
+
dst.file.name = e>> @f[:upload][:dst_file_base] + @f[:upload][:dot_full_extn]
|
17
|
+
dst.file.path = e>> File.join @f[:s3][:uploads_dir], @f[:upload][:dst_file_name]
|
@@ -0,0 +1,174 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# --
|
4
|
+
# -- Create dynamic secrets of various flavours including
|
5
|
+
# --
|
6
|
+
# -- - ssh public/private key secrets
|
7
|
+
# -- - secret keys for internal database services
|
8
|
+
# -- - hashed SHA256 keys for Jenkins user auth
|
9
|
+
# --
|
10
|
+
class Crypto
|
11
|
+
|
12
|
+
# --
|
13
|
+
# -- Get a viable machine password taking into account the human
|
14
|
+
# -- password length and the specified mix_ratio.
|
15
|
+
# --
|
16
|
+
# -- machine password length = human password length * mix_ratio - 1
|
17
|
+
# --
|
18
|
+
def self.get_amalgam_password human_password, machine_password, mix_ratio
|
19
|
+
|
20
|
+
size_error_msg = "Human pass length times mix_ratio must equal machine pass length."
|
21
|
+
lengths_are_perfect = human_password.length * mix_ratio == machine_password.length
|
22
|
+
raise ArgumentError.new size_error_msg unless lengths_are_perfect
|
23
|
+
|
24
|
+
machine_passwd_chunk = 0
|
25
|
+
amalgam_passwd_index = 0
|
26
|
+
amalgamated_password = ""
|
27
|
+
|
28
|
+
human_password.each_char do |passwd_char|
|
29
|
+
|
30
|
+
amalgamated_password[amalgam_passwd_index] = passwd_char
|
31
|
+
amalgam_passwd_index += 1
|
32
|
+
|
33
|
+
for i in 0..(mix_ratio-1) do
|
34
|
+
machine_pass_index = machine_passwd_chunk * mix_ratio + i
|
35
|
+
amalgamated_password[amalgam_passwd_index] = machine_password[machine_pass_index]
|
36
|
+
amalgam_passwd_index += 1
|
37
|
+
end
|
38
|
+
|
39
|
+
machine_passwd_chunk += 1
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
return amalgamated_password
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
# --
|
48
|
+
# -- Get a viable machine password taking into account the human
|
49
|
+
# -- password length and the specified mix_ratio.
|
50
|
+
# --
|
51
|
+
# -- machine password length = human password length * mix_ratio - 1
|
52
|
+
# --
|
53
|
+
def self.get_machine_password human_password_length, mix_ratio
|
54
|
+
|
55
|
+
machine_raw_secret = engineer_password( human_password_length * ( mix_ratio + 1) )
|
56
|
+
return machine_raw_secret[ 0..( human_password_length * mix_ratio - 1 ) ]
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
# --
|
62
|
+
# -- Collect a password from the user with a minimum length
|
63
|
+
# -- specified in the parameter.
|
64
|
+
# --
|
65
|
+
# -- An exception is raised if the minimum length is not at
|
66
|
+
# -- least 8 characters.
|
67
|
+
# --
|
68
|
+
def self.collect_secret minimum_size, prompt_1, prompt_2
|
69
|
+
|
70
|
+
assert_min_size minimum_size
|
71
|
+
|
72
|
+
sleep(1)
|
73
|
+
puts "\n#{prompt_1} : "
|
74
|
+
first_secret = STDIN.noecho(&:gets).chomp
|
75
|
+
|
76
|
+
assert_input_text_size first_secret.length, minimum_size
|
77
|
+
|
78
|
+
sleep(1)
|
79
|
+
puts "\n#{prompt_2} : "
|
80
|
+
check_secret = STDIN.noecho(&:gets).chomp
|
81
|
+
|
82
|
+
assert_same_size_text first_secret, check_secret
|
83
|
+
|
84
|
+
return first_secret
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
# --
|
90
|
+
# -- Engineer a raw password that is similar (approximate) in
|
91
|
+
# -- length to the integer parameter.
|
92
|
+
# --
|
93
|
+
def self.engineer_password approx_length
|
94
|
+
|
95
|
+
non_alphanum = SecureRandom.urlsafe_base64(approx_length);
|
96
|
+
return non_alphanum.delete("-_")
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
# --
|
102
|
+
# -- Raise an exception if asked to collect text that is less
|
103
|
+
# -- than 3 characters in length.
|
104
|
+
# --
|
105
|
+
def self.assert_min_size minimum_size
|
106
|
+
|
107
|
+
min_length_msg = "\n\nCrypts with 2 (or less) characters open up exploitable holes.\n\n"
|
108
|
+
raise ArgumentError.new min_length_msg if minimum_size < 3
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# --
|
114
|
+
# -- Output an error message and then exit if the entered input
|
115
|
+
# -- text size does not meet the minimum requirements.
|
116
|
+
# --
|
117
|
+
def self.assert_input_text_size input_size, minimum_size
|
118
|
+
|
119
|
+
if( input_size < minimum_size )
|
120
|
+
|
121
|
+
puts
|
122
|
+
puts "Input is too short. Please enter at least #{minimum_size} characters."
|
123
|
+
puts
|
124
|
+
|
125
|
+
exit
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
# --
|
133
|
+
# -- Assert that the text entered the second time is exactly (case sensitive)
|
134
|
+
# -- the same as the text entered the first time.
|
135
|
+
# --
|
136
|
+
def self.assert_same_size_text first_text, second_text
|
137
|
+
|
138
|
+
unless( first_text.eql? second_text )
|
139
|
+
|
140
|
+
puts
|
141
|
+
puts "Those two bits of text are not the same (in my book)!"
|
142
|
+
puts
|
143
|
+
|
144
|
+
exit
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
# --
|
152
|
+
# -- Print out the machine password that is to be kept as an environment variable
|
153
|
+
# -- on any workstation used for material decryption.
|
154
|
+
# --
|
155
|
+
# -- Remember that neither the human nor machine passwords are required for the
|
156
|
+
# -- encryption phase. That is the beauty of assymetric cryptography - you don't
|
157
|
+
# -- need a private key to encrypt - just the end user's public key.
|
158
|
+
# --
|
159
|
+
def self.print_secret_env_var env_var_name, env_var_value
|
160
|
+
|
161
|
+
machine_to_env_txt = "sudo echo \"#{env_var_name}=#{env_var_value}\" >> /etc/environment"
|
162
|
+
|
163
|
+
puts
|
164
|
+
puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
165
|
+
puts "@@@ Add as environment variable @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
166
|
+
puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
167
|
+
puts machine_to_env_txt
|
168
|
+
puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
169
|
+
puts
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
end
|