Class: Gas::Ssh
Class Method Summary
collapse
Methods included from Prompter
clean_gets, user_wants_gas_to_handle_rsa_keys?, user_wants_to_delete_all_ssh_data?, user_wants_to_install_key_to_github?, user_wants_to_overwrite_existing_rsa_key?, user_wants_to_remove_the_keys_that_already_exist_for_this_user?, user_wants_to_use_key_already_in_gas?, user_wants_to_use_key_already_in_ssh?
Class Method Details
.corresponding_rsa_files_exist?(nickname = '') ⇒ Boolean
9
10
11
12
13
|
# File 'lib/gas/ssh.rb', line 9
def self.corresponding_rsa_files_exist?(nickname = '')
nickname = @uid if nickname == ''
return true if File.exists? "#{GAS_DIRECTORY}/#{nickname}_id_rsa" and File.exists? "#{GAS_DIRECTORY}/#{nickname}_id_rsa.pub"
false
end
|
.current_key_already_backed_up? ⇒ Boolean
150
151
152
153
154
155
156
|
# File 'lib/gas/ssh.rb', line 150
def self.current_key_already_backed_up?
if scan_for_file_match(SSH_DIRECTORY + "/id_rsa", GAS_DIRECTORY) and scan_for_file_match(SSH_DIRECTORY + "/id_rsa.pub", GAS_DIRECTORY)
return true
else
return false
end
end
|
.delete(nickname) ⇒ Object
deletes the ssh keys associated with a user
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
|
# File 'lib/gas/ssh.rb', line 249
def self.delete(nickname)
return false unless user_has_ssh_keys?(nickname)
case Gas::Prompter.user_wants_to_delete_all_ssh_data?
when "a"
delete_associated_github_keys!(nickname)
delete_associated_local_keys!(nickname)
when "l"
delete_associated_local_keys!(nickname)
when "g"
delete_associated_github_keys!(nickname)
when "n"
return false
end
end
|
.delete_associated_github_keys!(nickname) ⇒ Object
271
272
273
274
275
276
277
278
279
280
|
# File 'lib/gas/ssh.rb', line 271
def self.delete_associated_github_keys!(nickname)
rsa = get_associated_rsa_key(nickname).first
credentials = get_nils
github_speaker = GithubSpeaker.new(nickname, credentials[:username], credentials[:password])
result = github_speaker.remove_key! rsa
puts "The key for this user was not in the specified github account's public keys section." if !result
end
|
.delete_associated_local_keys!(nickname) ⇒ Object
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
|
# File 'lib/gas/ssh.rb', line 286
def self.delete_associated_local_keys!(nickname)
puts "Removing associated keys from local machine..."
puts
ssh_file = get_md5_hash("#{SSH_DIRECTORY}/id_rsa")
gas_file = get_md5_hash("#{GAS_DIRECTORY}/#{nickname}_id_rsa")
return false if gas_file.nil?
if ssh_file == gas_file
File.delete("#{SSH_DIRECTORY}/id_rsa")
File.delete("#{SSH_DIRECTORY}/id_rsa.pub")
end
File.delete("#{GAS_DIRECTORY}/#{nickname}_id_rsa")
File.delete("#{GAS_DIRECTORY}/#{nickname}_id_rsa.pub")
end
|
.generate_new_rsa_keys_in_gas_dir ⇒ Object
Generates a new sshkey putting it in ~/.gas/nickname_id_rsa This function can get a little tricky. It’s best to strip off the comment here, because github API doesn’t retain the comment…
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
# File 'lib/gas/ssh.rb', line 33
def self.generate_new_rsa_keys_in_gas_dir
puts "Generating new ssh key..."
begin
k = SSHKey.generate()
publ = k.ssh_public_key
privl = k.private_key
my_file_privl = File.open(GAS_DIRECTORY + "/#{@uid}_id_rsa",'w',0700)
my_file_privl.write(privl)
my_file_privl.close
my_file_publ = File.open(GAS_DIRECTORY + "/#{@uid}_id_rsa.pub",'w',0700)
my_file_publ.write(publ)
my_file_publ.close
return true
rescue
puts "Fatal Error: Something unexpected happened while writing to #{GAS_DIRECTORY}/#{@uid}_id_rsa"
puts "SSH key not saved."
return false
end
end
|
.get_associated_rsa_key(nickname) ⇒ Object
Get’s the ~/.gas/user_id_rsa and ~/.gas/user_id_rsa.pub strings associated with the specified user and returns it as an array. Returns array with two nils if there’s no keys
- pub_rsa, priv_rsa
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
# File 'lib/gas/ssh.rb', line 206
def self.get_associated_rsa_key(nickname)
pub_path = "#{GAS_DIRECTORY}/#{nickname}_id_rsa.pub"
priv_path = "#{GAS_DIRECTORY}/#{nickname}_id_rsa"
if File.exists? pub_path and File.exists? priv_path
pub_file = File.open(pub_path, "rb")
pub_rsa = pub_file.read.strip
pub_file.close
if pub_rsa.count(' ') == 2 pub_rsa = pub_rsa.split(" ")
pub_rsa = "#{rsa[0]} #{rsa[1]}"
end
priv_file = File.open(priv_path, "rb")
priv_rsa = priv_file.read.strip
priv_file.close
return [pub_rsa, priv_rsa]
end
return [nil, nil]
end
|
.get_md5_hash(file_path) ⇒ Object
158
159
160
161
162
163
164
165
166
|
# File 'lib/gas/ssh.rb', line 158
def self.get_md5_hash(file_path)
if File.exists? file_path
file = File.open(file_path, "rb")
hash = Digest::MD5.hexdigest(file.read)
file.close
return hash
end
return nil
end
|
.get_nils ⇒ Object
this is just for testing… it gets stubbed… otherwise, the nils are normal and allow for normal prompting for username and password from within the GithubSpeaker class
284
|
# File 'lib/gas/ssh.rb', line 284
def self.get_nils; { :username => nil, :password => nil };end
|
.is_ssh_agent_there? ⇒ Boolean
243
244
245
246
|
# File 'lib/gas/ssh.rb', line 243
def self.is_ssh_agent_there?
return false if which("ssh-add").nil?
return true
end
|
.key_installation_routine!(user = nil, rsa_test = nil, github_speaker = nil) ⇒ Object
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
# File 'lib/gas/ssh.rb', line 176
def self.key_installation_routine!(user = nil, rsa_test = nil, github_speaker = nil)
@uid = user.nickname unless user.nil?
rsa_key = get_associated_rsa_key(@uid).first
rsa_key = rsa_test unless rsa_test.nil?
return false if rsa_key.nil?
github_speaker = GithubSpeaker.new(user) if github_speaker.nil?
puts github_speaker.status
if github_speaker.status == :bad_credentials
puts "Invalid credentials. Skipping upload of keys to github. "
puts "To try again, type $ gas ssh #{@uid}"
return false
end
result = github_speaker.post_key!(rsa_key)
if result
puts "Key uploaded successfully!"
return true
end
end
|
.scan_for_file_match(file_to_compare, dir_to_scan) ⇒ Object
This function scans each file in a directory to check to see if it is the same file which it’s being compared against dir_to_scan The target directory you’d like to scan file_to_compare The file’s path that you’re expecting to find
138
139
140
141
142
143
144
145
146
147
148
|
# File 'lib/gas/ssh.rb', line 138
def self.scan_for_file_match(file_to_compare, dir_to_scan)
pattern = get_md5_hash(file_to_compare)
@files = Dir.glob(dir_to_scan + "/*" + file_to_compare.split(//).last(1).to_s)
@files.each do |file|
return true if get_md5_hash(file) == pattern
end
return false
end
|
.setup_ssh_keys(user) ⇒ Object
This function creates the ssh keys if needed and puts them in ~/.gas/NICKNAME_id_rsa and …rsa.pub
.ssh_dir_contains_rsa? ⇒ Boolean
25
26
27
28
|
# File 'lib/gas/ssh.rb', line 25
def self.ssh_dir_contains_rsa?
return true if File.exists?(SSH_DIRECTORY + "/id_rsa") or File.exists?(SSH_DIRECTORY + "/id_rsa.pub")
return false
end
|
.swap_in_rsa(nickname) ⇒ Object
This huge method handles the swapping of id_rsa files on the hdd
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# File 'lib/gas/ssh.rb', line 84
def self.swap_in_rsa(nickname)
@uid = nickname
if corresponding_rsa_files_exist?
if ssh_dir_contains_rsa?
if current_key_already_backed_up?
write_to_ssh_dir!
else
if Gas::Prompter.user_wants_to_overwrite_existing_rsa_key?
write_to_ssh_dir!
else
puts "Proceeding without swapping rsa keys (aborting)."
end
end
else write_to_ssh_dir!
end
end
end
|
.upload_public_key_to_github(user, github_speaker = nil) ⇒ Object
.use_current_rsa_files_for_this_user(test = nil) ⇒ Object
Copies a key pair from ~/.ssh to .gas/Nickname*
16
17
18
19
20
21
22
23
|
# File 'lib/gas/ssh.rb', line 16
def self.use_current_rsa_files_for_this_user(test = nil)
@uid = test unless test.nil?
FileUtils.cp("#{SSH_DIRECTORY}/id_rsa", "#{GAS_DIRECTORY}/#{@uid}_id_rsa")
FileUtils.cp("#{SSH_DIRECTORY}/id_rsa.pub", "#{GAS_DIRECTORY}/#{@uid}_id_rsa.pub")
FileUtils.chmod 0700, "#{GAS_DIRECTORY}/#{@uid}_id_rsa"
FileUtils.chmod 0700, "#{GAS_DIRECTORY}/#{@uid}_id_rsa.pub"
return true
end
|
.user_has_ssh_keys?(nickname) ⇒ Boolean
266
267
268
269
|
# File 'lib/gas/ssh.rb', line 266
def self.user_has_ssh_keys?(nickname)
return false if get_associated_rsa_key(nickname).first.nil?
return true
end
|
.which(cmd) ⇒ Object
Cross-platform way of finding an executable in the $PATH. returns nil if command not present
which('ruby')
232
233
234
235
236
237
238
239
240
241
|
# File 'lib/gas/ssh.rb', line 232
def self.which(cmd)
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
exts.each { |ext|
exe = "#{path}/#{cmd}#{ext}"
return exe if File.executable? exe
}
end
return nil
end
|
.write_to_ssh_dir! ⇒ Object
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/gas/ssh.rb', line 107
def self.write_to_ssh_dir!
supress_process_output = "> /dev/null 2>&1"
supress_process_output = "> NUL" if IS_WINDOWS
system("ssh-add -d #{SSH_DIRECTORY}/id_rsa #{supress_process_output}") if is_ssh_agent_there?
FileUtils.cp(GAS_DIRECTORY + "/#{@uid}_id_rsa", SSH_DIRECTORY + "/id_rsa")
FileUtils.cp(GAS_DIRECTORY + "/#{@uid}_id_rsa.pub", SSH_DIRECTORY + "/id_rsa.pub")
FileUtils.chmod(0700, SSH_DIRECTORY + "/id_rsa")
FileUtils.chmod(0700, SSH_DIRECTORY + "/id_rsa.pub")
if is_ssh_agent_there?
`ssh-add #{SSH_DIRECTORY}/id_rsa #{supress_process_output}`
if $?.exitstatus == 1 puts "Looks like there may have been a fatal error in registering the rsa key with ssh-agent. Might be worth looking into"
raise "Exit code on ssh-add command line was one meaning: Error!"
end
else
puts "Slight Error: The key should now be in ~/.ssh so that's good, BUT ssh-add could not be found. If you're using windows, you'll need to use git bash or cygwin to emulate this unix command and actually do uploads."
end
end
|