safedb 0.01.0001

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.yardopts +3 -0
  4. data/Gemfile +10 -0
  5. data/LICENSE +21 -0
  6. data/README.md +793 -0
  7. data/Rakefile +16 -0
  8. data/bin/safe +5 -0
  9. data/lib/configs/README.md +58 -0
  10. data/lib/extension/array.rb +162 -0
  11. data/lib/extension/dir.rb +35 -0
  12. data/lib/extension/file.rb +123 -0
  13. data/lib/extension/hash.rb +33 -0
  14. data/lib/extension/string.rb +572 -0
  15. data/lib/factbase/facts.safedb.net.ini +38 -0
  16. data/lib/interprete.rb +462 -0
  17. data/lib/keytools/PRODUCE_RAND_SEQ_USING_DEV_URANDOM.txt +0 -0
  18. data/lib/keytools/kdf.api.rb +243 -0
  19. data/lib/keytools/kdf.bcrypt.rb +265 -0
  20. data/lib/keytools/kdf.pbkdf2.rb +262 -0
  21. data/lib/keytools/kdf.scrypt.rb +190 -0
  22. data/lib/keytools/key.64.rb +326 -0
  23. data/lib/keytools/key.algo.rb +109 -0
  24. data/lib/keytools/key.api.rb +1391 -0
  25. data/lib/keytools/key.db.rb +330 -0
  26. data/lib/keytools/key.docs.rb +195 -0
  27. data/lib/keytools/key.error.rb +110 -0
  28. data/lib/keytools/key.id.rb +271 -0
  29. data/lib/keytools/key.ident.rb +243 -0
  30. data/lib/keytools/key.iv.rb +107 -0
  31. data/lib/keytools/key.local.rb +259 -0
  32. data/lib/keytools/key.now.rb +402 -0
  33. data/lib/keytools/key.pair.rb +259 -0
  34. data/lib/keytools/key.pass.rb +120 -0
  35. data/lib/keytools/key.rb +585 -0
  36. data/lib/logging/gem.logging.rb +132 -0
  37. data/lib/modules/README.md +43 -0
  38. data/lib/modules/cryptology/aes-256.rb +154 -0
  39. data/lib/modules/cryptology/amalgam.rb +70 -0
  40. data/lib/modules/cryptology/blowfish.rb +130 -0
  41. data/lib/modules/cryptology/cipher.rb +207 -0
  42. data/lib/modules/cryptology/collect.rb +138 -0
  43. data/lib/modules/cryptology/crypt.io.rb +225 -0
  44. data/lib/modules/cryptology/engineer.rb +99 -0
  45. data/lib/modules/mappers/dictionary.rb +288 -0
  46. data/lib/modules/storage/coldstore.rb +186 -0
  47. data/lib/modules/storage/git.store.rb +399 -0
  48. data/lib/session/fact.finder.rb +334 -0
  49. data/lib/session/require.gem.rb +112 -0
  50. data/lib/session/time.stamp.rb +340 -0
  51. data/lib/session/user.home.rb +49 -0
  52. data/lib/usecase/cmd.rb +487 -0
  53. data/lib/usecase/config/README.md +57 -0
  54. data/lib/usecase/docker/README.md +146 -0
  55. data/lib/usecase/docker/docker.rb +49 -0
  56. data/lib/usecase/edit/README.md +43 -0
  57. data/lib/usecase/edit/delete.rb +46 -0
  58. data/lib/usecase/export.rb +40 -0
  59. data/lib/usecase/files/README.md +37 -0
  60. data/lib/usecase/files/eject.rb +56 -0
  61. data/lib/usecase/files/file_me.rb +78 -0
  62. data/lib/usecase/files/read.rb +169 -0
  63. data/lib/usecase/files/write.rb +89 -0
  64. data/lib/usecase/goto.rb +57 -0
  65. data/lib/usecase/id.rb +36 -0
  66. data/lib/usecase/import.rb +157 -0
  67. data/lib/usecase/init.rb +63 -0
  68. data/lib/usecase/jenkins/README.md +146 -0
  69. data/lib/usecase/jenkins/jenkins.rb +208 -0
  70. data/lib/usecase/login.rb +71 -0
  71. data/lib/usecase/logout.rb +28 -0
  72. data/lib/usecase/open.rb +71 -0
  73. data/lib/usecase/print.rb +40 -0
  74. data/lib/usecase/put.rb +81 -0
  75. data/lib/usecase/set.rb +44 -0
  76. data/lib/usecase/show.rb +138 -0
  77. data/lib/usecase/terraform/README.md +91 -0
  78. data/lib/usecase/terraform/terraform.rb +121 -0
  79. data/lib/usecase/token.rb +35 -0
  80. data/lib/usecase/update/README.md +55 -0
  81. data/lib/usecase/update/rename.rb +180 -0
  82. data/lib/usecase/use.rb +41 -0
  83. data/lib/usecase/verse.rb +20 -0
  84. data/lib/usecase/view.rb +71 -0
  85. data/lib/usecase/vpn/README.md +150 -0
  86. data/lib/usecase/vpn/vpn.ini +31 -0
  87. data/lib/usecase/vpn/vpn.rb +54 -0
  88. data/lib/version.rb +3 -0
  89. data/safedb.gemspec +34 -0
  90. metadata +193 -0
@@ -0,0 +1,55 @@
1
+
2
+
3
+ # safe rename
4
+
5
+ Changing your mind is a basic human right! In lieu of this, safe provides a **rename** use case that can be used to rename
6
+
7
+ - a chapter
8
+ - a verse
9
+ - a key (at a chapter and verse location)
10
+
11
+ <blockquote>
12
+ As yet safe has no command for renaming books. You can achieve this by first cloning the book then deleting the original.
13
+ </blockquote>
14
+
15
+ ## safe rename | chapter
16
+
17
+ To rename a chapter you must not have an open location. If you do you must first close it before renaming.
18
+
19
+ $ safe close
20
+ $ safe view
21
+ $ safe rename <old-name> <new-name>
22
+
23
+ When safe sees that the book is not open, it knows that you want to rename the chapter.
24
+
25
+ The rename command returns a view allowing you to check that the chapter name has indeed been updated.
26
+
27
+
28
+ ## safe rename | verse
29
+
30
+ To rename the verse you must have its chapter (and only its chapter) open.
31
+
32
+ $ safe close
33
+ $ safe open <chapter>
34
+ $ safe view
35
+ $ safe rename <old-name> <new-name>
36
+
37
+ The rename command returns a view of all the verses in the open chapter allowing you to check that the verse name has indeed been updated.
38
+
39
+ ## safe rename | key
40
+
41
+ Most of the time you will want to rename keys in the mini-dictionary at a chapter and verse location. To do this you must open the chapter and verse first.
42
+
43
+ $ safe open <chapter> <verse>
44
+ $ safe show
45
+ $ safe rename <old-name> <new-name>
46
+
47
+ The rename command shows you the mini-dictionary (hashing out sensitive credentials) allowing you to check that the key name has indeed been updated.
48
+
49
+ ## safe rename | be aware
50
+
51
+ Be aware of the following when renaming.
52
+
53
+ - key names that start with @ guard the key's value during a safe show
54
+ - renaming keys that are required for integration functionality will need you pass the --force switch
55
+
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # The <b>put use case</b> follows <b>open</b> and it adds secrets into an
6
+ # <em>(encrypted at rest)</em> <b>envelope</b>. Put can be called many times
7
+ # and when done, the <b>lock use case</b> can be called to commit all opened
8
+ # secrets into the configured storage engines.
9
+ #
10
+ # Calling <em>put</em> <b>before</b> calling open or <b>after</b> calling lock
11
+ # is not allowed and will result in an error.
12
+ #
13
+ # == Put Pre-Conditions
14
+ #
15
+ # When the put use case is called - the below conditions ring true.
16
+ #
17
+ # - the <b>folder path</b> ending in ../../my must exist
18
+ # - a session id, filename and encryption key ( in workstation config )
19
+ #
20
+ # == Observable Value
21
+ #
22
+ # The observable value delivered by +put+ boils down to
23
+ #
24
+ # - a new <b>friends.xyz123abc.os.txt</b> file if this is the first put.
25
+ # - a new group_name/key_name (like monica/surname) entry is added if required
26
+ # - a secret value is added against the key or updated if it already exists
27
+ # - a new session id and encryption key is generated and used to re-encrypt
28
+ #
29
+ # == Example | Bill Clinton's Secrets
30
+ #
31
+ # In our fictitious example Bill Clinton uses safe to lock away the
32
+ # names and dates of his lady friends.
33
+ #
34
+ # $ safe init bill.clinton@example.com
35
+ # $ safe open my/friends
36
+ #
37
+ # $ safe put monica/surname lewinsky
38
+ # $ safe put monica/from "April 1989"
39
+ # $ safe put monica/to "September 1994"
40
+ #
41
+ # $ safe put hilary/surname clinton
42
+ # $ safe put hilary/from "January 1988"
43
+ # $ safe put hilary/to "Present Day"
44
+ #
45
+ # $ safe lock
46
+ #
47
+ # Soon follow up use cases will be unveiled, enabling us to
48
+ #
49
+ # - <b>get</b>
50
+ # - <b>read</b>
51
+ # - <b>list</b>
52
+ # - <b>look</b>
53
+ # - <b>peep</b> and
54
+ # - <b>peek</b>
55
+ class Rename < UseCase
56
+
57
+
58
+ attr_writer :secret_id, :secret_value
59
+
60
+
61
+ # The <b>put use case</b> follows <b>open</b> and it adds secrets into an
62
+ # <em>(encrypted at rest)</em> envelope. Put can be called many times to
63
+ # add secrets. Finally the <b>lock use case</b> commits all opened secrets
64
+ # into the configured storage engines.
65
+ #
66
+ # Calling <em>put</em> <b>before</b> calling open or <b>after</b> calling lock
67
+ # is not allowed and will result in an error.
68
+ #
69
+ # == Put Pre-Conditions
70
+ #
71
+ # When the put use case is called - the below conditions ring true.
72
+ #
73
+ # - the <b>folder path</b> ending in ../../my must exist
74
+ # - a session id, filename and encryption key ( in workstation config )
75
+ #
76
+ # == Observable Value
77
+ #
78
+ # The observable value delivered by +put+ boils down to
79
+ #
80
+ # - a new <b>friends.xyz123abc.os.txt</b> file if this is the first put.
81
+ # - a new group_name/key_name (like monica/surname) entry is added if required
82
+ # - a secret value is added against the key or updated if it already exists
83
+ # - a new session id and encryption key is generated and used to re-encrypt
84
+ #
85
+ # == How to Pretty Print a Hash in JSON Format
86
+ #
87
+ # This pretty prints a Hash (dictionary) data structure in JSON format.
88
+ #
89
+ # puts "---\n"
90
+ # puts JSON.pretty_generate( master_db )
91
+ # puts "---\n"
92
+ #
93
+ def execute
94
+
95
+ return unless ops_key_exists?
96
+ master_db = KeyApi.read_master_db()
97
+
98
+ return if unopened_envelope?( master_db )
99
+
100
+ envelope_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
101
+ has_content = KeyApi.db_envelope_exists?( master_db[ envelope_id ] )
102
+
103
+ # --
104
+ # -- To get hold of the content we must either
105
+ # --
106
+ # -- a) unlock it using the breadcrumbs or
107
+ # -- b) start afresh with a new content db
108
+ # --
109
+ content_box = KeyDb.from_json( KeyApi.content_unlock( master_db[ envelope_id ] ) ) if has_content
110
+ content_box = KeyDb.new() unless has_content
111
+ content_hdr = create_header()
112
+
113
+ # --
114
+ # -- If no content envelope exists we need to place
115
+ # -- an empty one inside the appdb content database.
116
+ # --
117
+ master_db[ envelope_id ] = {} unless has_content
118
+
119
+ # --
120
+ # -- This is the PUT use case so we append a
121
+ # --
122
+ # -- a) key for the new dictionary entry
123
+ # -- b) value for the new dictionary entry
124
+ # --
125
+ # -- into the current content envelope and write
126
+ # -- the envelope to the content filepath.
127
+ # --
128
+ crumbs_dict = master_db[ envelope_id ]
129
+ content_box.create_entry( master_db[ KEY_PATH ], @secret_id, @secret_value )
130
+ KeyApi.content_lock( crumbs_dict, content_box.to_json, content_hdr )
131
+
132
+ # --
133
+ # -- Three envelope crumbs namely the external ID, the
134
+ # -- random iv and the crypt key are written afresh into
135
+ # -- the master database.
136
+ # --
137
+ KeyApi.write_master_db( content_hdr, master_db )
138
+ print_put_success
139
+
140
+ # ---> secret_ids = @secret_id.split("/")
141
+ # ---> if ( envelope.has_key? secret_ids.first )
142
+ # ---> envelope[secret_ids.first][secret_ids.last] = @secret_value
143
+ # ---> else
144
+ # ---> envelope[secret_ids.first] = { secret_ids.last => @secret_value }
145
+ # ---> end
146
+
147
+ end
148
+
149
+
150
+ private
151
+
152
+
153
+ def print_put_success
154
+
155
+ puts ""
156
+ puts "Success putting a key/value pair into the open envelope."
157
+ puts "You can put more in and then close the envelope."
158
+ puts ""
159
+ puts " #{COMMANDMENT} close"
160
+ puts ""
161
+
162
+ end
163
+
164
+
165
+ # Perform pre-conditional validations in preparation to executing the main flow
166
+ # of events for this use case. This method may throw the below exceptions.
167
+ #
168
+ # @raise [SafeDirNotConfigured] if the safe's url has not been configured
169
+ # @raise [EmailAddrNotConfigured] if the email address has not been configured
170
+ # @raise [StoreUrlNotConfigured] if the crypt store url is not configured
171
+ def pre_validation
172
+
173
+
174
+ end
175
+
176
+
177
+ end
178
+
179
+
180
+ end
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # The <b>use <em>use case</em></b> borrowed from the database world denotes which
6
+ # domain will be used <b>for now (and evermore)</b> on the workstation until another
7
+ # use command is issued.
8
+ #
9
+ # == Observable Value
10
+ #
11
+ # The workstation configuration file will point to the domain name specified
12
+ # marking it as the current and correct domain to use.
13
+ #
14
+ # == Alternative / Error Flows
15
+ #
16
+ # Error - if the domain name is not listed in the configuration file.
17
+ # Error - if the (dictionary) path to the domain's base does not exist
18
+ #
19
+ class Use < UseCase
20
+
21
+ attr_writer :domain_name
22
+
23
+
24
+ # The <b>use <em>use case</em></b> is borrowed from the database world and it denotes
25
+ # the domain to be used <b>for now (and evermore)</b> for this workstation until another
26
+ # use command is issued.
27
+ #
28
+ # The parameter domain_name must be set after an object instance is acquired but
29
+ # before the execute method runs.
30
+ def execute
31
+ end
32
+
33
+
34
+ def pre_validation
35
+ end
36
+
37
+
38
+ end
39
+
40
+
41
+ end
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ class Verse < UseCase
6
+
7
+ def execute
8
+
9
+ return unless ops_key_exists?
10
+ master_db = get_master_database()
11
+ return if unopened_envelope?( master_db )
12
+ print master_db[ KEY_PATH ]
13
+
14
+ end
15
+
16
+
17
+ end
18
+
19
+
20
+ end
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # View provides a bird's eye view of the domain's content and links well with
6
+ # the <b>goto</b>, <b>show</b> and <b>tell</b> commands.
7
+ #
8
+ # $ xxx view
9
+ # $ xxx goto 5 # shortcut for xxx open <<envelope_name>> <<key_name>>
10
+ # $ xxx show
11
+ # $ xxx tell
12
+ # $ xxx tell url
13
+ #
14
+ # View maps out and numbers each envelope/key combination.
15
+ # Goto with the number effectively shortcuts the open pinpointer.
16
+ # Show prints out the dictionary at the opened path but masks any secrets.
17
+ # Tell without a parameter echoes the secret.
18
+ # Tell with parameter echoes the value of the parameter key (eg url).
19
+ #
20
+ # Once goto is enacted all path CRUD commands come into play as if you had
21
+ # opened the path. These include put, copy, paste, show, tell and delete.
22
+ class View < UseCase
23
+
24
+ def execute
25
+
26
+ return unless ops_key_exists?
27
+ master_db = KeyApi.read_master_db()
28
+
29
+ open_envelope = "(none)" if master_db[ ENV_PATH ].nil?
30
+ open_envelope = master_db[ ENV_PATH ] unless master_db[ ENV_PATH ].nil?
31
+ open_key_path = "(none)" if master_db[ KEY_PATH ].nil?
32
+ open_key_path = master_db[ KEY_PATH ] unless master_db[ KEY_PATH ].nil?
33
+
34
+ puts ""
35
+ puts "--- Book Birthday ~> #{KeyApi.to_db_create_date(master_db)}\n"
36
+ puts "--- The Book Name ~> #{KeyApi.to_db_domain_name(master_db)}\n"
37
+ puts "--- The Book (Id) ~> #{KeyApi.to_db_domain_id(master_db)}\n"
38
+ puts "---\n"
39
+ puts "--- Chapter ~> #{open_envelope}\n"
40
+ puts "--- + Verse ~> #{open_key_path}\n"
41
+ puts "---\n"
42
+
43
+ goto_location = 1
44
+ envelope_dictionaries = KeyApi.to_matching_dictionary( master_db, ENVELOPE_KEY_PREFIX )
45
+ envelope_dictionaries.each_pair do | envelope_name, crumb_dictionary |
46
+ is_opened_chapter = envelope_name.eql?( open_envelope )
47
+ envelope_content = KeyDb.from_json( KeyApi.content_unlock( crumb_dictionary ) )
48
+ envelope_content.each_key do | envelope_key |
49
+ is_opened_verse = envelope_key.eql?( open_key_path )
50
+ is_open = is_opened_chapter && is_opened_verse
51
+ openend = is_open ? " (( open location ))" : ""
52
+ fixdint = format( "%02d", goto_location )
53
+ goindex = is_open ? "" : "[#{fixdint}] "
54
+ puts "--- --- --------------------------------------" if is_open
55
+ puts "--- #{goindex}#{envelope_name} ~> #{envelope_key}#{openend}\n"
56
+ puts "--- --- --------------------------------------" if is_open
57
+ goto_location += 1
58
+ end
59
+ end
60
+
61
+ puts ""
62
+
63
+ return
64
+
65
+ end
66
+
67
+
68
+ end
69
+
70
+
71
+ end
@@ -0,0 +1,150 @@
1
+
2
+ # Switch On an OpenVPN Client Connection
3
+
4
+ safe vpn
5
+
6
+ ## Introduction
7
+
8
+ This DevOps task is a collaboration to **switch on a VPN connection** with safe as the credentials provider, nmcli on Ubuntu and an OpenVPN account embodied details within an ovpn file.
9
+
10
+ ## Task Preconditions
11
+
12
+ To switch on a client OpenVPN connection the following must hold true
13
+
14
+ - a shell safe tokenize, login and open has ocurred
15
+ - the opened safe location must have a key vpn.id
16
+ - safe write <<runtime.dir>> must eject <<vpn.id>>.ovpn
17
+ - the ovpn file must be valid and point to a running accessible openvpn server
18
+ - the ubiquitous @password field must hold a credible value
19
+ - the VPN connection is assumed to be not just switched off, but deleted (at the start)
20
+
21
+
22
+
23
+
24
+ # Switch Off an OpenVPN Client Connection
25
+
26
+ dot vpn down
27
+
28
+ ## Introduction
29
+
30
+ This DevOps task is a collaboration to **switch on a VPN connection** with safe as the credentials provider, nmcli on Ubuntu and an OpenVPN account embodied details within an ovpn file.
31
+
32
+ ## Task Preconditions
33
+
34
+ To switch on a client OpenVPN connection the following must hold true
35
+
36
+ - a shell safe tokenize, login and open has ocurred
37
+ - the opened safe location must have a key vpn.id
38
+ - safe write <<runtime.dir>> must eject <<vpn.id>>.ovpn
39
+ - the ovpn file must be valid and point to a running accessible openvpn server
40
+ - the ubiquitous @password field must hold a credible value
41
+ - the VPN connection is assumed to be not just switched off, but deleted (at the start)
42
+
43
+
44
+ # safe vpn up | safe vpn down
45
+
46
+ $ safe open vpn production
47
+ $ safe vpn up
48
+ $ ... (do work using vpn)
49
+ $ safe vpn down
50
+
51
+ ## safe vpn | introduction
52
+
53
+ Once you put VPN credentials into a mini-dictionary (in a safe book chapter and verse), you can bring up a VPN connection and after doing your work through the VPN you can tear it down.
54
+
55
+ **[The strategy used to bring the OpenVPN connection up and down can be found here.](http://www.devopswiki.co.uk/wiki/middleware/network/openvpn/openvpn)**
56
+
57
+
58
+ ### safe vpn | ovpn | requirements
59
+
60
+ Currently the safe vpn command is only integration tested with the following tech requirements
61
+
62
+ - an Ubuntu 16.04 and Ubuntu 18.04 operating system
63
+ - the nmcli (network manager command line) client which is installed if absent
64
+ - an OpenVPN server
65
+ - VPN configuration imported via an OpenVPN **`*.ovpn`** file
66
+
67
+
68
+ ## safe terraform | credential creation
69
+
70
+ The first use case is importing the IAM user credentials into safe.
71
+
72
+ $ safe login joebloggs.com # open the book
73
+ $ safe open iam dev.s3.writer # open chapter and verse
74
+ $ safe put @access.key ABCD1234EFGH5678 # Put IAM access key in safe
75
+ $ safe put @secret.key xyzabcd1234efgh5678 # Put IAM secret key in safe
76
+ $ safe put region.key eu-west-3 # infrastructure in Paris
77
+
78
+ $ safe open iam prod.provisioner # open chapter and verse
79
+ $ safe put @access.key 4321DCBA8765WXYZ # Put IAM access key in safe
80
+ $ safe put @secret.key 5678uvwx4321abcd9876 # Put IAM secret key in safe
81
+ $ safe put region.key eu-west-1 # infrastructure in Dublin
82
+
83
+ safe logout
84
+
85
+ Take care to specify these 3 key names **@access.key**, **@secret.key**, **region.key** and note that safe's convention is to sensitively treat the value's of keys beginning with an **@** sign. **safe show** and other readers **mask out (redact)** these sensitive values.
86
+
87
+
88
+ ## safe terraform | running terraform
89
+
90
+ Now and forever you can return to the chapter and verse and enjoy a secure credentials transfer where safe makes the IAM user credentials available to Terraform via environment variables. **Never do the plain text credentials touch the floor (disk).**
91
+
92
+ ### Why no safe terraform init?
93
+ **safe only gets involved when credentials are involved**.
94
+ **safe** is not trying to wrap command willy nilly. safe's policy is to keep external tool interfaces as **small** as possible. **`terraform init .`** does not involve credentials so safe does not get involved.
95
+
96
+ $ cd /path/to/terraform/dir # go to directory holding your .tf file
97
+ $ safe login joebloggs.com # login to your chosen book
98
+ $ safe open iam dev.s3.writer # open chapter and verse holding IAM creds
99
+ $ terraform init . # the usual terraform init command
100
+ $ safe terraform plan # credentials are exported then terraform plan is run
101
+ $ safe terraform apply # credentials are exported then terraform apply is run
102
+ $ safe terraform destroy # credentials are exported then terraform destroy is run
103
+
104
+ You can even change directories and run other terraform projects against the opened IAM user. You can also open an IAM user, run commands, open another run commands and then reopen the first and run commands.
105
+
106
+ As long as you stay within your shell window - your safe login will persist. Once your session is finished you either logout or exit the shell.
107
+
108
+ ### Shortcut Alert
109
+
110
+ **safe terraform** is a shortcut for **safe terraform apply**
111
+
112
+ $ safe terraform apply
113
+ $ safe terraform
114
+
115
+ ## safe terraform | pre-conditions
116
+
117
+ To enact a successful safe terraform call you will need
118
+
119
+ - to have created an IAM user
120
+ - to open chapter and verse which
121
+ - has these 3 keys @access.key @secret.key and region.key (at least)
122
+ - terraform installed on the machine or container
123
+
124
+
125
+ ## safe terraform | benefits
126
+
127
+ The safe terraform command is both an ultra secure and extremely convenient way of launching terraform.
128
+
129
+ Your precious AWS IAM user credentials do not leave the safe and exist within (environment variable) memory only for the duration of the terraform command.
130
+
131
+ It is safe as you need neither expose your AWS credentials in plain text in **~/.aws/credentials**, nor risk them sliding into version control. It is convenient because switching IAM users and AWS regions is as easy as typing the now ubiquitous safe open command.
132
+
133
+
134
+ ## quick tip | view then goto
135
+
136
+ No need to type out the safe open command everytime. Use it the very first time you create a path to chapter and verse.
137
+
138
+ safe open <<chapter>> <<verse>>
139
+
140
+ Then use safe view and safe goto instead of safe open.
141
+
142
+ $ safe view # list all chapter and verses
143
+ $ safe goto <<index>> # use the number from safe view to open the location
144
+ $ safe show # look at your mini dictionary
145
+
146
+
147
+
148
+
149
+
150
+
@@ -0,0 +1,31 @@
1
+
2
+ [vpn]
3
+
4
+ vpn.id = rb>> @f[:secrets][:vpn_id]
5
+ vpn.filename = rb>> @s[:vpn_id] + ".ovpn"
6
+ export.folder = rb>> File.join( Dir.home, ".config/safe.db" )
7
+ vpn.filepath = rb>> File.join( @s[:export_folder], @s[:vpn_filename] )
8
+ vpn.username = rb>> @f[:secrets][:username]
9
+ vpn.password = rb>> @f[:secrets][:@password]
10
+ safe.write.cmd = rb>> "safe write --script " + @s[:vpn_filepath]
11
+
12
+ nm.import.cmd = rb>> "sudo nmcli connection import type openvpn file " + @s[:vpn_filepath]
13
+ nm.default.cmd = rb>> "nmcli connection modify " + @s[:vpn_id] + " ipv4.never-default true"
14
+ nm.user.cmd = rb>> "nmcli connection modify " + @s[:vpn_id] + " +vpn.data username=" + @s[:vpn_username]
15
+ nm.reload.cmd = rb>> "sudo nmcli connection reload " + @s[:vpn_id]
16
+ nm.flags.cmd = rb>> "nmcli connection modify " + @s[:vpn_id] + " +vpn.data password-flags=0"
17
+ this.user = rb>> Etc.getlogin()
18
+
19
+ nm.directory = /etc/NetworkManager/system-connections
20
+ nm.filepath = rb>> File.join @s[:nm_directory], @s[:vpn_id]
21
+ nm.cache.name = rb>> @s[:vpn_id] + ".ini"
22
+ nm.cache.path = rb>> File.join( Gem.user_home(), @s[:nm_cache_name] )
23
+
24
+ chown.cmd.1 = rb>> "sudo chown " + @s[:this_user] + ":" + @s[:this_user] + " " + @s[:nm_filepath]
25
+ chown.cmd.2 = rb>> "sudo chown root:root " + @s[:nm_filepath]
26
+
27
+ nm.conn.up = rb>> "nmcli connection up " + @s[:vpn_id]
28
+ nm.restart = sudo service network-manager restart
29
+
30
+ nm.conn.off = rb>> "nmcli con down id " + @s[:vpn_id]
31
+ nm.conn.del = rb>> "nmcli connection delete " + @s[:vpn_id]
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # This vpn use case sets up vpn connection paraphernelia and can bring up a VPN connection
6
+ # and then tear it down.
7
+ #
8
+ # safe vpn up
9
+ # safe vpn down
10
+ class Vpn < UseCase
11
+
12
+ attr_writer :command
13
+
14
+ def execute
15
+
16
+ if( @command && @command.eql?( "down" ) )
17
+
18
+ puts ""
19
+ system @dictionary[ :nm_conn_off ]; sleep 2;
20
+ system @dictionary[ :nm_conn_del ]
21
+ puts ""
22
+ return
23
+
24
+ end
25
+
26
+ puts ""
27
+ system @dictionary[ :safe_write_cmd ]
28
+ puts "[#{@dictionary[ :vpn_filename ]}] temporarily exported to [#{@dictionary[ :vpn_filepath ]}]."
29
+ system @dictionary[ :nm_import_cmd ]
30
+ File.delete( @dictionary[ :vpn_filepath ] )
31
+ puts "Exported file [#{@dictionary[ :vpn_filepath ]}] has now been deleted."
32
+
33
+ system @dictionary[ :nm_default_cmd ]
34
+ system @dictionary[ :nm_user_cmd ]
35
+ system @dictionary[ :nm_reload_cmd ]
36
+ system @dictionary[ :nm_flags_cmd ]
37
+ system @dictionary[ :chown_cmd_1 ]
38
+
39
+ vpn_data = IniFile.load( @dictionary[:nm_filepath] )
40
+ vpn_data['vpn-secrets'] = { 'password' => @dictionary[:vpn_password] }
41
+ vpn_data.write()
42
+
43
+ system @dictionary[ :chown_cmd_2 ]
44
+ system @dictionary[ :nm_restart ]; sleep 2;
45
+ system @dictionary[ :nm_conn_up ]
46
+ puts ""
47
+
48
+ end
49
+
50
+
51
+ end
52
+
53
+
54
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module SafeDb
2
+ VERSION = "0.01.0001"
3
+ end
data/safedb.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'version'
5
+
6
+ Gem::Specification.new do |spec|
7
+
8
+ spec.name = "safedb"
9
+ spec.version = SafeDb::VERSION
10
+ spec.authors = [ "Apollo Akora" ]
11
+ spec.email = [ "devopsassets@gmail.com" ]
12
+
13
+ spec.summary = %q{safe locks and unlocks secrets in a simple, secure and intuitive way.}
14
+ spec.description = %q{safe is a credentials manager for the linux command line written in Ruby. It locks and unlocks secrets in a safe simple and intuitive manner. You can then visit websites, manufacture keys and passwords, inject credentials into Jenkins, and interact with many tools including S3, GoogleDrive, Terraform, Git and Docker.}
15
+ spec.homepage = "https://www.safedb.net"
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features)/})
20
+ end
21
+
22
+ spec.metadata["yard.run"] = "yri"
23
+ spec.bindir = "bin"
24
+ spec.executables = [ 'safe' ]
25
+ spec.require_paths = ["lib"]
26
+ spec.required_ruby_version = '>= 2.5.0'
27
+
28
+ spec.add_dependency 'inifile', '~> 3.0'
29
+ spec.add_dependency 'thor', '~> 0.2'
30
+ spec.add_dependency 'bcrypt'
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.16"
33
+
34
+ end